Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is authoring TP in .NET 8 unsupported? #408

Open
cannorin opened this issue Jun 30, 2024 · 8 comments
Open

Is authoring TP in .NET 8 unsupported? #408

cannorin opened this issue Jun 30, 2024 · 8 comments

Comments

@cannorin
Copy link
Member

Description

We F#+ team are trying to migrate our entire codebase to F# 8 and net8, dropping older framework versions including net45 and even netstandard2.0. However, our type provider project seemingly produces an invalid assembly once we switch it to net8.

The TP project compiles just fine, but the consuming project fails to compile with the following error:

FSC : warning FS3005: Referenced assembly '.../src/obj/Debug/net8.0/ref/FSharpPlus.Providers.dll' has assembly level attribute 'Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute' but no public type provider classes were found

Is this a known limitation on authoring type providers in net8 or is this rather an unexpected issue?

Repro steps

We have created a small project that reproduces the above error.

We used the type provider template from FSharp.TypeProviders.Templates, merged the runtime and design time projects to make it resemble our setup, and upgraded everything to use F# 8 and net8.

https://github.com/cannorin/net8-typeprovider-fail-repro/tree/simple

Here is the actual error message from a CI log:
https://github.com/cannorin/net8-typeprovider-fail-repro/actions/runs/9658205746/job/26638915041

Expected behavior

TP projects built in net8 must be consumable.

Actual behavior

The consuming project fails to compile with the above error.

Known workarounds

Keep using netstandard2.0.

Related

fsprojects/FSharpPlus#604

@cartermp
Copy link
Contributor

cartermp commented Jul 1, 2024

@vzarytovskii miiiight be good for your team to look at this one. I could probably fumble my way around but my knowledge cutoff date is .NET 6

@vzarytovskii
Copy link

vzarytovskii commented Jul 1, 2024

@vzarytovskii miiiight be good for your team to look at this one. I could probably fumble my way around but my knowledge cutoff date is .NET 6

Not in the comings weeks/months for sure, we're busy with .NET 9 release as well as engineering work. Also, doubtful that anyone from the team knows anything about TP SDK (from non-compiler POV).

Additionally, non- .NET standard 2.0 providers (or their design-time part rather) won't work in VS (probably Rider as well, since they run FCS in full CLR host process, IIRC).

@vzarytovskii
Copy link

Oh and this issue might be related to refassemblies (which are produced by default by net8+ compiler), try switching it off - <ProduceReferenceAssembly>false</ProduceReferenceAssembly>

@cannorin
Copy link
Member Author

cannorin commented Jul 2, 2024

@vzarytovskii Disabling refassemblies actually makes the project compile and the tests run successfully. Thank you! As you have mentioned, however, Ionide-VSCode (and thus FSAC) seems to hang when trying to typecheck the test project. So my conclusion is that net8 TP projects are effectively unconsumable at the moment, and it is a known limitation.

@vzarytovskii
Copy link

@baronfel might actually know better what's happening in ionide. Technically compiler doesn't care much which target tp is, it's just if it's design time, tooling needs to be able to load that target.

@baronfel
Copy link
Contributor

baronfel commented Jul 2, 2024

I don't immediately know what happens in Ionide here - we don't have any tests covering TP usage directly nor do we do any explicit customization of the compiler around them so it should be 'vanilla' out of the box behavior.

@Thorium
Copy link
Member

Thorium commented Jul 5, 2024

Just general notes and questions (as TP structure is not very well documented):

  • The TypeProviderAssemblyAttribute has to be publicly visible. Is it, if it's inside modules? Or should the Repro.DesignTime.fs module ReproImplementation be namespace ReproImplementation ?
  • TypeProviderAssemblyAttribute is needed only runtime. As you link the file containing that to both projects, you may want to add a directive to not include that in design-time just for easier debugging.
  • Does that need ".dll" to the end?
#if !IS_DESIGNTIME
// Put the TypeProviderAssemblyAttribute in the runtime DLL, pointing to the design-time DLL
[<assembly:CompilerServices.TypeProviderAssembly("Repro.DesignTime.dll")>]
do ()
#endif
  • Is there some kind of naming conventions for fsproj properties like <Name>Repro</Name> or assembly attributes like [<assembly: AssemblyTitleAttribute("Repro")>] that is used to decide the linking?
  • As far as I understand the project reference is not needed, it's just for ensure that the desgin-time dll is actually done building before the runtime executes. So you could do it also e.g. something like this in Repro.Runtime.fsproj without a project reference:
    <Target Name="BeforeBuild">
      <MSBuild Projects="..\Repro.DesignTime\Repro.DesignTime.fsproj" Targets="Build" Properties="Configuration=$(Configuration);TargetFramework=net8.0" />
    </Target>

As Vlad pointed above, to run VS2022 intellisense you need NetStandard 2.0, so your .NET8-only TP would work only with dotnet.exe and VS Code.

@DedSec256
Copy link

Additionally, non- .NET standard 2.0 providers (or their design-time part rather) won't work in VS (probably Rider as well, since they run FCS in full CLR host process, IIRC).

Rider enables by default the ability to launch type providers in a separate process on the same runtime that MsBuild runs when project build

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants