Skip to content

Instantly share code, notes, and snippets.

@bleis-tift
Created May 9, 2012 05:25
Show Gist options
  • Save bleis-tift/2642085 to your computer and use it in GitHub Desktop.
Save bleis-tift/2642085 to your computer and use it in GitHub Desktop.
fsharp-typeclasses的な型クラスを使おうとするとコンパイラが落ちるバグの再現手順

バグ再現手順

http://code.google.com/p/fsharp-typeclasses/ てきな型クラスを使おうとすると、コンパイラがNullReferenceExceptionを吐いて落ちることがある。 VS2010でもVS11betaでも再現する。

手順

  1. 2つのライブラリプロジェクト(TypeClassLibとClientとする)を用意する

  2. TypeClassLibにSystem.XmlとSystem.Xml.Linqへの参照を追加する

  3. ClientにTypeClassLibへの参照を追加する

  4. TypeClassLibに以下のコードを追加する

     module TypeClassLib
     open System.Xml.Linq
     type Foo = Foo with
       static member (?<-) (_, _: Foo, _: string) = ()
       static member (?<-) (_, _: Foo, _: XElement) = ()
     let inline f (a: ^a ) =
       () ? (Foo) <- a
    
  5. Clientに以下のコードを追加する

     let a = TypeClassLib.f ""
    
  6. この状態でビルドすると内部エラーが発生

補足

  1. XElementをintやStringBuilder等に変更すると内部エラーは発生しない

  2. XElementをXNameに変更すると内部エラーは発生しない

  3. XElementを直接使わず、

     type X = X of XElement
    

    としてXElementをXに変更すると内部エラーは発生しない

  4. XElementをXmlDocumentに変更すると内部エラーは発生しない

コンパイラへの潜り方

  1. http://igeta-diary.blogspot.jp/2011/12/build-your-next.html などを参考に、F#のコンパイラをビルドする

  2. Dドライブ直下にfsharpディレクトリを作ったとして、src/all-vs2010.slnを開いてTypeClassLibとClientプロジェクトを上の「手順」を参考に作成

  3. Clientプロジェクトはアンロードしておく

  4. Fscプロジェクトのプロパティを開き、デバッグタブの引数の欄に以下を参考にコマンドライン引数を追加

     -r System.Xml -r System.Xml.Linq -r D:\fsharp\src\TypeClassLib\bin\Debug\TypeClassLib.dll D:\fsharp\src\Client\Module1.fs
    
  5. ビルド

  6. tast.fsの1340行目が例外を発生させる場所なので、とりあえずそこにブレークポイントはっておく

  7. F5でデバッグ実行して、呼び出し履歴とか駆使してLet's調査

注意点としては、Proto/cli/4.0/bin/Microsoft.FSharp-proto.targetsがないとプロジェクトが開けないので、all-vs2010.slnを開く前にちゃんとビルドしておくこと。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment