Scalaコンパイラのクラッシュを回避するにはどうすればよいですか?

私はScala 2.9.1でプロジェクトをコンパイルしています。

java.lang.AssertionError: assertion failed
    at scala.Predef$.assert(Predef.scala:89)
    at scala.tools.nsc.symtab.Symbols$Symbol.accessed(Symbols.scala:1142)
    at scala.tools.nsc.symtab.Symbols$Symbol.accessed(Symbols.scala:1138)
    at scala.tools.nsc.transform.Mixin$MixinTransformer$$anonfun$buildFieldPositions$1$1.apply(Mixin.scala:1006)

私はそれがバグだと思うが、私は本当にそれを修正するか、誰かがそれを修正するのを待つ時間がないので、バグにぶつからないように私が何をしているのかを変更したい。

しかし、私のコードのどの部分が問題を引き起こしたのか分からないので、苦労しています。問題を特定するために私が使用できる戦略はありますか?

調査している人の作業を簡単にするために、ソースコードへのリンクを以下に示します。

3
原因を見つけた場合はバグを報告してください。
追加された 著者 soc,
何時でも @transient アノテーションがありますか?
追加された 著者 Daniel C. Sobral,

4 答え

具体的にはScalaコンパイラのクラッシュについては取り組んでいませんが、他のコンパイラクラッシュを回避しました。あなたがしたいのは、問題の原因を絞り込むことです。ほとんどのプロジェクトでこれを行う最も簡単な方法は、コメントを使ってバイナリ検索を行うことです。つまり、コードの約半分をコメントアウトし、バグがまだ発生しているかどうかを確認します。そうでない場合は、その半分のコメントを外し、残りの半分にコメントして、まだバグが起きているかどうかを確認してください。それで、これがうまくいくとすれば、それがどちらの半分で起こっているのかを見て、それをコメントで半分にします。あなたが見つけ出すことのできるコードの最小セグメントまで、このプロセスを繰り返します。 (明らかに、コードの依存関係のために半分にすることはできないかもしれませんが、少なくともそれを大きな断片に分割する方法を見つけることはできません)。

あなたがそこに着くと、私の経験上、コンパイラのクラッシュが、間違って形成されたコードによって引き起こされる可能性が高いため、そのコードにバグがあることを検査で見つけることができます。期待していない。たとえば、自分のIntellisenseのようなJavaモジュールは、私が仕事をしているときには、スーパーやフォレストのスーパーをフォローしていない人は想像できないので、 foo(super).bar 文法がどのように設計されたかによってパーサーに伝わる。 AdobeのActionscriptコンパイラは、 var x:int = 10; ではなく var x:int:10; を書いたときにクラッシュします。前回私が使ったときにクラッシュした)。したがって、コード内にバグが見つかった場合は、修正してください。そうでない場合は、コードが異なるように書き直してください。うまくいけば、コンパイラがクラッシュしないバージョンを見つけることができます。

2
追加された
ありがとうございました。コメント付きのバイナリ検索。私は以前に答えていただろうが、そのプロジェクトは私の時間を圧倒していた。
追加された 著者 Owen,
お役に立てて嬉しいです!
追加された 著者 Keith Irwin,

コンパイル中にprintln コードを実行させることができれば、すぐに絞り込むことができます。だから何か同等のことをしないのはなぜですか?

0.0.0                                //Lexer will choke on this (I think)
val var;                             //Parser will choke on this
val Some(x) = None;                  //Second pass will, I think, choke on this
Option(2) match { case Some(x) => x }//Will emit warning in late phase and continue

コンパイラが窒息する前にどれだけ離れているかを調べるために、さまざまな場所でこれらのコードをテストとしてドロップすることができます。これはコードのコメントブロック/コメント解除のほうが現実的かもしれないいくつかの行に絞り込むべきです。

また、あなたがこのようなものに遭遇したときに、最初から構築するようにしてください。互換性のないバージョンが存在し、変更を取得するために何かを再コンパイルする必要があると認識しない場合、コンパイラは時には終了します。

2
追加された
@レックスカー:エラーメッセージに続いている間に私はそれを見つけました。... damnit ...最初のエラーメッセージは見ませんでした。私は愚かだ。ごめんなさい。
追加された 著者 soc,
フェーズを制限したい場合は、そのためのコンパイラフラグがあります。
追加された 著者 Daniel C. Sobral,
@こんにちは、私はそれを何かに等しくしようとはしていませんでした。
追加された 著者 Rex Kerr,

Scalaトランクはより多くの情報を表示するので、より良いエラーメッセージを得るためにトランクでコンパイルすることができれば助けになります。もちろん、トランクにはこのバグはないかもしれませんが、一発の価値があります。

トランクでコンパイルが役に立たない場合は、ここで私が知っていることがあります。これはgetterとsetterに関連しています。コードから、セッターかゲッターのどちらかになります。ゲッターやセッターが定義されていないときに呼び出されるもののようです。あなたはそれらを見ることができます。

また、ゲッターやセッタールールにも注意してください。 getterは、少なくともsetterと同じくらいの可視性を持つ必要があります(つまり、setterがパブリックな場合など)。ここではコンパイラのバグについて話しているので、私は奇妙な可視性(つまり、公開でもプライベートでもないもの)、継承や混合された可視性(例えば、セッターのプライベートとゲッターの公開)を避けるでしょう。

EDIT: I just noticed the stack trace mentions mixin as well. So, it is related to a getter or setter which is defined in a trait and used on a class, or used on a trait.

EDIT 2: Still investigating. Do you have overload getters/setters for lazy vals, or getters/setters being overloaded with lazy vals? Or, just lazy vals on traits? I saw something in the third line of the trace that seems to point to a lazy val.

より多くの情報が見つかった場合は、小さなケースを再現して問題を提出してください。

1
追加された

ソース管理を使用していて、段階的に作業している(ソース管理を使用していて、増分的に作業している場合は)、問題の原因をすでに知っている - それは最後に変更したものです。漸進的に作業してきたので、これは小さな変更になります。ソースコントロールを使用していたので、完了したすべてのものの完全な履歴があるため、正確に何がわかりますか。

この変更を、問題を再現する最小限の変更(おそらく、バイナリチョップを使用して)にします。この変更に関する何かが "奇妙な"ものになり、それがコンパイラを混乱させる原因になります。この "奇妙な"ことが何であっても、あなたの回避策があれば問題を解決する方法を見つけてください。

しかし、それを行う前に、バグを報告してください(コンパイラがクラッシュする場合は間違いなくバグです)。それを示す小さな例とともに報告してください。

インクリメンタルに作業していないし、ソース管理を使用していない場合、多くの面倒な作業があります。

  1. まず、どのファイルが問題を引き起こしているのかを調べます(バイナリチョップを使用して、単一のファイルを特定するまでこれを絞り込みます)。
  2. 次に、問題の原因となっているファイルのビットを特定します(バイナリチョップ)。
  3. 単一の単純な変更があるまで、バイナリチョッピングを続けます。
1
追加された