fsprojects / IfSharp

F# for Jupyter Notebooks
Other
440 stars 71 forks source link

.NET Core + Type Providers #206

Open rudihorn opened 5 years ago

rudihorn commented 5 years ago

Description

There is some issue loading the correct libraries to use Type Providers on .NET Core. While this is directly relevant to Type Providers, the issue itself is broader and should be solved.

Repro steps

Run the following code: image

The problem can slightly be improved by manually loading some further libraries: image

This still yields the error: image

Known workarounds

Not known yet.

Related information

rudihorn commented 5 years ago

The complaint about netstandard.dll is a bit more worrying, as it refuses to load the netstandard library when you try to force load it. I'm assuming this is an issue with the setup of the environment.

cgravill commented 5 years ago

Does the type provider work correctly in an F# Interactive session outside of IFSharp? My understanding is that each of the parts is only recently working on .NET Core.

Getting this working also would be great!

rudihorn commented 5 years ago

Yes and interestingly it is actually possible to execute code such as:

image

It is more the library implementation that is causing issues.

rudihorn commented 5 years ago

The main difference I can see between fsi.exe and IfSharp is that fsi.exe calls FsiEvaluationSession.GetDefaultConfiguration with useAuxLib=true, while IfSharp sets it to false. Setting it to true in IfSharp causes an exception to be thrown:

Unhandled Exception: System.TypeInitializationException: The type initializer for '<StartupCode$IfSharp-Kernel>.$Evaluation' threw an exception. ---> System.Exception: Error creating evaluation session: StopProcessingExn None at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1647.Invoke(String message) at FSharp.Compiler.Interactive.Shell.FsiEvaluationSession..ctor(FsiEvaluationSessionHostConfig fsi, String[] argv, TextReader inReader, TextWriter outWriter, TextWriter errorWriter, Boolean fsiCollectible, FSharpOption1 legacyReferenceResolver) at FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.Create(FsiEvaluationSessionHostConfig fsiConfig, String[] argv, TextReader inReader, TextWriter outWriter, TextWriter errorWriter, FSharpOption1 collectible, FSharpOption1 legacyReferenceResolver) at IfSharp.Kernel.Evaluation.startSession() in /home/administrator/IfSharp/src/IfSharp.Kernel/Evaluation.fs:line 61 at <StartupCode$IfSharp-Kernel>.$Evaluation..cctor() in /home/administrator/IfSharp/src/IfSharp.Kernel/Evaluation.fs:line 80 --- End of inner exception stack trace --- at IfSharp.Kernel.Evaluation.get_fsiEval() at IfSharp.Kernel.IfSharpKernel.doShell() in /home/administrator/IfSharp/src/IfSharp.Kernel/Kernel.fs:line 626 at <StartupCode$IfSharp-Kernel>.$Kernel.StartAsync@727.Invoke(Unit unitVar) in /home/administrator/IfSharp/src/IfSharp.Kernel/Kernel.fs:line 727 at Microsoft.FSharp.Control.AsyncPrimitives.CallThenInvoke[T,TResult](AsyncActivation1 ctxt, TResult result1, FSharpFunc2 part2) at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc2 firstAction) --- End of stack trace from previous location where exception was thrown --- at Microsoft.FSharp.Control.AsyncPrimitives.Start@938-1.Invoke(ExceptionDispatchInfo edi) at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc`2 firstAction) at <StartupCode$FSharp-Core>.$Async.-ctor@167-1.Invoke(Object o) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location where exception was thrown --- at System.Threading.ThreadPoolWorkQueue.Dispatch()

I'm guessing this is thrown in fsi.fs at line 2533 onwards:

    let (tcGlobals,frameworkTcImports,nonFrameworkResolutions,unresolvedReferences) = 
        try 
            let tcConfig = tcConfigP.Get(ctokStartup)
            checker.FrameworkImportsCache.Get (ctokStartup, tcConfig) |> Cancellable.runWithoutCancellation
        with e -> 
            stopProcessingRecovery e range0; failwithf "Error creating evaluation session: %A" e

    let tcImports =  
      try 
          TcImports.BuildNonFrameworkTcImports(ctokStartup, tcConfigP, tcGlobals, frameworkTcImports, nonFrameworkResolutions, unresolvedReferences) |> Cancellable.runWithoutCancellation
      with e -> 
          stopProcessingRecovery e range0; failwithf "Error creating evaluation session: %A" e

Not entirely sure what the useAuxLib property does internally though.

rudihorn commented 5 years ago

Does the type provider work correctly in an F# Interactive session outside of IFSharp? My understanding is that each of the parts is only recently working on .NET Core.

Turns out this might have been key. I added a forced reference to Microsoft.NETCore.App version 2.2.3, and it seems to now be "somewhat working". Previously it would automatically set the a reference to that library to version 2.2.0 in IfSharpNetCore.runtimeconfig.json, but with the additional reference it explicitly has a dependency of 2.2.3 and works.

It still requires the manual loading of some additional libraries, and Intellisense is still complaining about missing "netstandard.dll", but the functionality works :) I'll submit a PR soon.

Edit: Ignore this comment it, the error was only the intellisense / typechecking and not an issue with the execution. The highlighting issue is not solved.

rudihorn commented 5 years ago

Should libraries which are normally loaded during common projects such as "System.Runtime.Extensions.dll" be loaded by default though? Especially if they are needed by something like Type providers?

cgravill commented 5 years ago

I've add the automatic referencing of netstandard in #218 so the highlighting issue should be solved. I'm not sure the right answer about automatically referencing other libraries, it's convenient but may turn out problematic and a breaking change if we have to withdraw it later...

cgravill commented 5 years ago

Btw I also made the Paket helper script work better in netcore, it might help getting the right dlls referenced too.

cgravill commented 5 years ago

I gave this a go with the latest and it seems to working for me now: image

The error highlighting looks to be a false positive: image

Based on this issue: https://github.com/dotnet/fsharp/issues/6688 it may not be anything specific to IF#

rudihorn commented 5 years ago

@cgravill your sample code seems to work for me, except for the issue mention in #232

rudihorn commented 5 years ago

I suppose a lot of this may be redundant with https://github.com/dotnet/fsharp/pull/5850.

cgravill commented 5 years ago

Yes, I'm very hopeful about that change to #r. We could also potentially just use FAKE's current syntax which implements an approximation to it: https://github.com/fsprojects/IfSharp/issues/112#issuecomment-504662581 which now supports unmanaged references too.