13.2. 既知のバグと問題点

バグトラッカには、報告されたもののまだ修正されていないGHCのバグが列挙されている。GHC Tracを見よ。加えて、GHCには、既知のバグや問題点として以下のものがある。これらはより永続的である。つまり、これらはどれも短期的に修正される可能性が低い。

13.2.1. GHCのバグ

  • GHCは、漏れのあるパターンや重複パターンについて警告することができる。(4.8. 警告と正気度チェックのためのオプションを見よ)。これは大抵の場合正しく動作するが、そうでないこともある。文字列パターンやガードがあると混乱し、不要な警告を出力することがある。本当は重複検査のコード全体を総点検する必要がある。

  • GHCは、データ型の文脈に、そのデータ型のパラメタ以外の型変数が出現することを許していない。例を挙げる。

      data C a b => T a = MkT a
    

    MkTの型は以下のようになるはずである。

      MkT :: forall a b. C a b => a -> T a
    

    原理的には、関数従属を使った適切なクラス宣言があれば、この型が曖昧でないこともあり得る。それでもGHCはこれを受け付けない。データ型宣言の文脈中に現れる型変数はそのデータ型の型パラメタのどれかでなければならない。

  • 再帰をデータ型にエンコードする標準的な方法を使うと、GHCのインライン化器を停止しないようにすることができる。

      data U = MkU (U -> Bool)
    
      russel :: U -> Bool
      russel u@(MkU p) = not $ p u
    
      x :: Bool
      x = russel (MkU russel)
    

    この不自然な例以外に、GHCを発散させるプログラムの形は見付かっていず、この問題を修正しようとするとあらゆるコンパイルにオーバーヘッドが掛かることになるので、このバグは修正されないままになっている。さらなる背景情報はSecrets of the GHC inlinerにある。

  • インスタンス宣言が他のパッケージから取り込まれた場合、どれが「スコープにあるか」についてGHCは細かく管理しない。GHCがそのパッケージで見かけたインスタンス宣言は、そのパッケージ由来のモジュールがコマンド行の式で使われているかどうかに依らず、あらゆる場所でスコープに入る。このバグが影響するのは--makeモードとGHCiだけである。

  • 「存在型を持つレコード」の拡張(7.4.5.3. レコード構築子を参照)を使う場合、モジュールの分割コンパイルが壊れている。回避方法としては、毎回cleanして--make付きでビルドするか、6.7開発スナップショットを使うという方法しかない。詳細はtrac bug #933を見よ。

13.2.2. GHCi(対話的GHC)のバグ

  • GHCiは、利用中のスコープのモジュールにあるdefault宣言を考慮せず、コマンド行に打ち込まれた式については、デフォルトのデフォルト化を行う。すなわち、default(Int,Double)である。

    GHCiがそれぞれのモジュールのデフォルト設定を覚えておいて、「現在の」モジュール(どういう意味かは別にして)のものを使うようにした方が良いだろう。

  • Windowsでは、GNU ld/BFDにバグがあり、0xffff個よりも多くの再配置のある、正しくないPEオブジェクトファイルを出力することがある。このバグに影響されたパッケージをGHCiがロードしようとすると、次のような形式のメッセージが得られる。

    Loading package javavm ... linking ... WARNING: Overflown relocation field (# relocs found: 30765)
    

    我々が最後に確認したときはこのバグはまだBFDのコードベースにあり、2001年あたりにこのバグが報告されて以来、興味がもたれた様子もない。

    回避するには、パッケージを構成する.oファイルを複数個の.oに分ければ良い。これは「base」パッケージが行っていることである。