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.93k stars 787 forks source link

Missing assembly reference for type used in attributes #7861

Open auduchinok opened 5 years ago

auduchinok commented 5 years ago

Consider an attribute having a public property with a type from System.Drawing assembly defined in a net461 class library project:

namespace AttributeAssemblyReferenceRepro

open System
open System.Drawing


type FooAttribute() =
    inherit Attribute()

    member val Prop: FontStyle = Unchecked.defaultof<_> with get, set

When used in another net461 project, it doesn't make the compiler generate a reference to System.Drawing assembly in the output assembly.

module Module

open System.Drawing
open AttributeAssemblyReferenceRepro

[<Foo(Prop = FontStyle.Bold)>]
do ()

A workaround is to use any type from System.Drawing somehow else, so the missing reference is added:

type T(p: FontStyle) =
    class end

The following .NET Core SDK is used:

$ dotnet --version
3.0.100
dsyme commented 4 years ago

The problem here is that assembly references are not being determined from attributes in refs_of_tdef and refs_of_mdef etc in il.fs

There is now enough information in both encoded and decoded attributes to do this

dsyme commented 2 years ago

Fixed

auduchinok commented 2 years ago

@dsyme I've tried to remove the workaround with additional explicit reference today, and it seems it hasn't been fixed:

Loading an assembly “System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”
  which is not listed in assembly references of assembly “JetBrains.ReSharper.Plugins.FSharp.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=333a98252ac829ae”
  when trying to resolve the type System.Drawing.FontStyle.
  A type reference points into an assembly not listed among assembly references.
auduchinok commented 2 years ago

See my comment here: https://github.com/dotnet/fsharp/pull/12937/files#r955124576

It looks like the problem remains here due to the literal reference is erased during IL types generation. We only have a literal value represented by the underlying type here, instead of the reference like FontStyle.Bold, as in https://github.com/dotnet/fsharp/issues/7861, that could be used to add a type reference to the output assembly.

auduchinok commented 2 years ago

If the literal reference is removed too early and is not easy to get back at this point, could using the type of the attribute field/property help?