Skip to content

FSharp.Compiler.Service problems

MIYAZAKI Shohei edited this page Feb 5, 2016 · 5 revisions

FSharp.Compiler.Service (2.0.0.2) で確認

推論されたfloatがいろいろとおかしい

メソッドの引数、戻り値がfloatに推論された場合にfloat<MeasureOne>が返る なぜか単位?のようなものが付いてくる。

分かっていること

  1. (t: FSharpType).TypeDefinition.FullNameが"Microsoft.FSharp.Core.float`1"
  2. (t: FSharpType).IsAbbreviationfalse
  3. (t: FSharpType).GenericArgumentsMeasureOneが含まれる

再現コード

type A() =
  static member InferencedFloatType(x) = 0.0 + x

明示的に型を指定すると発生しない。

type A() =
  static member FloatType(x: float): float = 0.0 + x

int, singleでは発生しない。

デバッグメッセージが標準出力に表示される。

mscorlibの要素(どの要素かは特定していない)にアクセスすると

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\mscorlib.dll: unexpected native type, nt = 47

と表示される。

無理やり表示させなくしよう。

  typeof<FSharpChecker>.Assembly.GetType("Microsoft.FSharp.Compiler.AbstractIL.Diagnostics")
  |> Option.ofObj
  |> Option.bind (fun diagMod -> diagMod.GetMember("diagnosticsLog", BindingFlags.NonPublic ||| BindingFlags.Static) |> Array.tryHead)
  |> Option.bind (tryUnbox<PropertyInfo>)
  |> Option.bind (fun x -> x.GetValue(null) |> Option.ofObj)
  |> Option.bind (tryUnbox<ref<Option<System.IO.TextWriter>>>)
  |> Option.iter (fun x -> x := None)

CompilerServiceで取得できないシグネチャが存在する

例えばこの辺り

int等の最適化があるが、実際にCompilerServiceで取得できるのは

when ^T : ^T = ((^T or ^U): (static member (+) : ^T * ^U -> ^V) (x,y))

のみ。しかも、System.Int32構造体には(+)演算子が定義されていない。このあたりはハードコードで定義しないとダメかも。

C#で定義した型のフィールドを取得できない。

または、取得方法がわからない。 プロパティは取得できる。F#で定義した型のフィールドは取得できる。