fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

TAST issues with Unions with values

Open TheAngryByrd opened this issue 5 years ago • 1 comments

Hey there! I've been working on some F# Analyzers using the SDK project. While running against the Typed AST I've a problem. When trying to get a TAST with a union that contains values such as type Foo = | Bar of int, I get an exception FSharp.Compiler.Service cannot yet return this kind of pattern match in the results: and other types are no longer resolved. This results in my analyzers failing to find any problems with the source code.

TAST without the DU
File without DU
module md5create
open System.Security.Cryptography
open System.Text

let foo () =
    use md5 = MD5.Create()
    md5.ComputeHash(UTF8Encoding().GetBytes("foo"))


[Entity 
   (md5create,
    [MemberOrFunctionOrValue
       (val foo,[[val unitVar0]],
        Let
  ((val md5, Call (None,member Create,[],[],[])),
   TryFinally
  (Call
  (Some Value val md5,member ComputeHash,[],[],
   [Call
  (Some NewObject (member .ctor,[],[]),member GetBytes,[],[],
   [Const ("foo",type Microsoft.FSharp.Core.string)])]),
   IfThenElse
  (TypeTest
  (type System.IDisposable,Coerce (type Microsoft.FSharp.Core.obj,Value val md5)),
   Call
  (Some
     Call
  (None,val UnboxGeneric,[],[type System.IDisposable],
   [Coerce (type Microsoft.FSharp.Core.obj,Value val md5)]),
   member Dispose,[],[],[]),
   Const (null,type Microsoft.FSharp.Core.unit)))))])]
File with DU
module md5create
open System.Security.Cryptography
open System.Text

type Foo = | Bar of int

let foo () =
    use md5 = MD5.Create()
    md5.ComputeHash(UTF8Encoding().GetBytes("foo"))


TAST with the DU
[Entity
   (md5create,
    [Entity (Foo,[]);
     MemberOrFunctionOrValue
       (member CompareTo,[[val this]; [val obj]],
        <ToString exception: FSharp.Compiler.Service cannot yet return this kind of pattern match at /Users/jimmybyrd/Documents/GitHub/BinaryDefense.FSharp.Analyzers/tests/BinaryDefense.FSharp.Analyzers.Tests/../examples/hashing/md5create.fs (5,5--5,8) IsSynthetic=false>);
     MemberOrFunctionOrValue
       (member CompareTo,[[val this]; [val obj]],
        Call
  (Some Value val this,member CompareTo,[],[],
   [Coerce (type md5create.Foo,Value val obj)]));
     MemberOrFunctionOrValue
       (member CompareTo,[[val this]; [val obj; val comp]],
        <ToString exception: FSharp.Compiler.Service cannot yet return this kind of pattern match at /Users/jimmybyrd/Documents/GitHub/BinaryDefense.FSharp.Analyzers/tests/BinaryDefense.FSharp.Analyzers.Tests/../examples/hashing/md5create.fs (5,5--5,8) IsSynthetic=false>);
     MemberOrFunctionOrValue
       (member GetHashCode,[[val this]; [val comp]],
        <ToString exception: FSharp.Compiler.Service cannot yet return this kind of pattern match at /Users/jimmybyrd/Documents/GitHub/BinaryDefense.FSharp.Analyzers/tests/BinaryDefense.FSharp.Analyzers.Tests/../examples/hashing/md5create.fs (5,5--5,8) IsSynthetic=false>);
     MemberOrFunctionOrValue
       (member GetHashCode,[[val this]; [val unitArg]],
        Call
  (Some Value val this,member GetHashCode,[],[],
   [ILAsm
  ("[I_call
   (Normalcall,
    Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer(...)(...),
    None)]",
   [],[])]));
     MemberOrFunctionOrValue
       (member Equals,[[val this]; [val obj; val comp]],
        <ToString exception: FSharp.Compiler.Service cannot yet return this kind of pattern match at /Users/jimmybyrd/Documents/GitHub/BinaryDefense.FSharp.Analyzers/tests/BinaryDefense.FSharp.Analyzers.Tests/../examples/hashing/md5create.fs (5,5--5,8) IsSynthetic=false>);
     MemberOrFunctionOrValue
       (member Equals,[[val this]; [val obj]],
        <ToString exception: FSharp.Compiler.Service cannot yet return this kind of pattern match at /Users/jimmybyrd/Documents/GitHub/BinaryDefense.FSharp.Analyzers/tests/BinaryDefense.FSharp.Analyzers.Tests/../examples/hashing/md5create.fs (5,5--5,8) IsSynthetic=false>);
     MemberOrFunctionOrValue
       (member Equals,[[val this]; [val obj]],
        IfThenElse
  (TypeTest (type md5create.Foo,Value val obj),
   Call
  (Some Value val this,member Equals,[],[],
   [Call (None,val UnboxGeneric,[],[type md5create.Foo],[Value val obj])]),
   Const (false,type Microsoft.FSharp.Core.bool)));
     MemberOrFunctionOrValue
       (val foo,[[val unitVar0]],
        Let
  ((val md5, Call (None,member Create,[],[],[])),
   TryFinally
  (Call
  (Some Value val md5,member ComputeHash,[],[],
   [Call
  (Some NewObject (member .ctor,[],[]),member GetBytes,[],[],
   [Const ("foo",type Microsoft.FSharp.Core.string)])]),
   IfThenElse
  (TypeTest
  (type System.IDisposable,Coerce (type Microsoft.FSharp.Core.obj,Value val md5)),
   Call
  (Some
     Call
  (None,val UnboxGeneric,[],[type System.IDisposable],
   [Coerce (type Microsoft.FSharp.Core.obj,Value val md5)]),
   member Dispose,[],[],[]),
   Const (null,type Microsoft.FSharp.Core.unit)))))])]

Repro steps

Provide the steps required to reproduce the problem:

  1. Clone: https://github.com/BinaryDefense/BinaryDefense.FSharp.Analyzers
  2. run ./build.sh dotnettest (or cmd if on windows)
  3. See tests succeed
  4. Edit tests/examples/hashing/md5create.fs and add type Foo = | Bar of int
  5. run ./build.sh dotnettest (or cmd if on windows)
  6. See tests fail

If possible attach a zip file with the repro case. This often makes it easier for others to reproduce. The zip file should ideally represent the situation just before the call/step that is problematic.

Expected behavior

Provide a description of the expected behavior.

Actual behavior

Provide a description of the actual behaviour observed.

Known workarounds

Provide a description of any known workarounds.

Related information

Provide any related information (optional):

FSharp.Compiler.Service (34.1.1).

  • Operating system: macOS

  • .NET Runtime kind (.NET Core, .NET Framework, Mono)

$ dotnet --info ``` .NET Core SDK (reflecting any global.json): Version: 3.1.200 Commit: c5123d973b

Runtime Environment: OS Name: Mac OS X OS Version: 10.14 OS Platform: Darwin RID: osx.10.14-x64 Base Path: /usr/local/share/dotnet/sdk/3.1.200/

Host (useful for support): Version: 3.1.2 Commit: 916b5cba26

.NET Core SDKs installed: 1.0.0-preview2.1-003155 [/usr/local/share/dotnet/sdk] 1.0.0-preview2-003121 [/usr/local/share/dotnet/sdk] 1.0.0-preview2-003131 [/usr/local/share/dotnet/sdk] 1.0.0-preview2-003156 [/usr/local/share/dotnet/sdk] 1.0.0-preview2-1-003177 [/usr/local/share/dotnet/sdk] 1.0.0-preview4-004233 [/usr/local/share/dotnet/sdk] 1.0.0-rc4-004711 [/usr/local/share/dotnet/sdk] 1.0.0-rc4-004771 [/usr/local/share/dotnet/sdk] 1.0.1 [/usr/local/share/dotnet/sdk] 1.0.4 [/usr/local/share/dotnet/sdk] 2.0.0 [/usr/local/share/dotnet/sdk] 2.0.3 [/usr/local/share/dotnet/sdk] 2.1.3 [/usr/local/share/dotnet/sdk] 2.1.4 [/usr/local/share/dotnet/sdk] 2.1.101 [/usr/local/share/dotnet/sdk] 2.1.200 [/usr/local/share/dotnet/sdk] 2.1.300-rc1-008673 [/usr/local/share/dotnet/sdk] 2.1.300 [/usr/local/share/dotnet/sdk] 2.1.401 [/usr/local/share/dotnet/sdk] 2.1.403 [/usr/local/share/dotnet/sdk] 2.1.603 [/usr/local/share/dotnet/sdk] 2.1.802 [/usr/local/share/dotnet/sdk] 2.2.102 [/usr/local/share/dotnet/sdk] 2.2.104 [/usr/local/share/dotnet/sdk] 2.2.105 [/usr/local/share/dotnet/sdk] 2.2.203 [/usr/local/share/dotnet/sdk] 3.0.100-preview7-012821 [/usr/local/share/dotnet/sdk] 3.0.100-preview8-013656 [/usr/local/share/dotnet/sdk] 3.0.100-preview9-014004 [/usr/local/share/dotnet/sdk] 3.0.100 [/usr/local/share/dotnet/sdk] 3.1.100 [/usr/local/share/dotnet/sdk] 3.1.102 [/usr/local/share/dotnet/sdk] 3.1.200 [/usr/local/share/dotnet/sdk]

.NET Core runtimes installed: Microsoft.AspNetCore.All 2.1.0-rc1-final [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.5 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.10 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.13 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.2 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.0-rc1-final [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.5 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.10 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.13 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.2 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0-preview7.19365.7 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0-preview8.19405.7 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0-preview9.19424.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.2 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 1.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 1.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 1.0.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 1.0.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 1.0.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 1.1.0-preview1-001100-00 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 1.1.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 1.1.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 1.1.2 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.6 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.7 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.0-rc1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.10 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.13 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.2 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.0-preview7-27912-14 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.0-preview9-19423-09 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.2 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

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


</details>

TheAngryByrd avatar Mar 31 '20 22:03 TheAngryByrd

Tracking as a feature request, since this appears to be an unimeplemented scenario in the FCS expression API here: https://github.com/dotnet/fsharp/blob/be621d8725e3ea88cb832f4d457bc0bf377172ed/src/fsharp/symbols/Exprs.fs#L1172

Unfortunately I think only @dsyme has familiarity with this, since the expression API is not a part of the compiler proper. Perhaps @ncave and @alfonsogarciacaro can weigh in here since Fable uses this API extensively.

We'd certainly welcome a pull request here and we're happy to review it. But I'm not sure this will be a high priority for us to implement right now since no supported F# editor tooling makes use of this.

cartermp avatar Apr 02 '20 18:04 cartermp