Как я могу обойти сбой компилятора Scala? - PullRequest
3 голосов
/ 13 ноября 2011

Я компилирую проект с 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)

Я думаю, что это ошибка, но у меня нет времени, чтобы ее исправить, или жду, пока кто-нибудь другой исправит ее,так что я хотел бы просто изменить то, что я делаю, чтобы не допустить ошибки.

Но мне трудно, потому что я не понимаю, какая часть моего кода вызвала проблему,Есть ли какие-либо стратегии, которые я могу использовать, чтобы изолировать проблему?

Чтобы облегчить задачу тем, кто занимается расследованиями, вот ссылки на исходный код:

Ответы [ 4 ]

2 голосов
/ 13 ноября 2011

Если бы вы могли заставить свой код печатать при компиляции , я уверен, что вы могли бы сузить его в кратчайшие сроки. Так почему бы не сделать что-то эквивалентное?

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 голосов
/ 13 ноября 2011

В частности, я не работал со сбоями компилятора Scala, но я работал над другими сбоями компилятора.Что вы хотите сделать, это попытаться сузить, что вызывает проблему.Самый простой способ сделать это в большинстве проектов - это выполнить бинарный поиск с помощью комментариев.То есть закомментируйте примерно половину кода и посмотрите, не возникла ли ошибка.Если нет, раскомментируйте эту половину и прокомментируйте другую половину и посмотрите, не произошла ли ошибка.Затем, предполагая, что это работает, и вы обнаружите, в какой половине это происходит, разбейте это пополам с помощью комментариев.Повторяйте этот процесс, пока не дойдете до самого маленького сегмента кода, который вы можете найти, который все еще ломает вещи.(Очевидно, что вы не всегда сможете сделать даже половинки из-за зависимостей кода, но найдите способы разбить его, по крайней мере, на большие куски).

Когда вы туда попадете, вы можете обнаружить, проверяяв том, что в этом коде есть ошибка, потому что сбой компилятора, по моему опыту, более вероятно вызван неправильно сформированным кодом, который неправильно сформирован так, как не ожидал автор компилятора.Например, мой собственный интеллигентный подобный Java-модуль, который я написал для работы, зависнет на foo(super).bar, потому что я никогда не думал, что кто-то не будет следовать за super с точкой или открытым пареном, но он может проскользнуть через синтаксический анализатор из-за грамматикиразработан.И компилятор Adobe ActionScript вылетел бы, когда вы написали var x:int : 10;, а не var x:int = 10; (возможно, они исправили это сейчас, но там он вылетал в прошлый раз, когда я его использовал).Итак, если вы нашли ошибку в своем коде, исправьте ее.Если нет, просто попробуйте переписать этот код, чтобы он стал другим.Надеюсь, вы сможете найти версию, которая не вызывает сбой компилятора.

1 голос
/ 13 ноября 2011

Магистраль Scala выводит дополнительную информацию, поэтому, если бы вы могли скомпилировать ее с транком, просто чтобы получить лучшее сообщение об ошибке, это помогло бы.Конечно, возможно, что в trunk нет этой ошибки, но стоит попробовать.

Если компиляция с использованием trunk не помогает, вот что я знаю.Это связано с геттерами и сеттерами.Из кода это может быть либо установщик, либо получатель.Кажется, это то, что вызывается, когда метод получения или установки используется , не определен.Вы можете посмотреть их.

Также, пожалуйста, обратите внимание на правила получения и установки.Получатель должен иметь как минимум такую ​​же видимость, что и установщик (т. Е. Общедоступный, если установщик общедоступен и т. Д.).И, поскольку мы говорим здесь об ошибке компилятора, я бы избегал странных (например, ничего не открытого или закрытого), наследования или смешанных (например, закрытых сеттеров и открытых геттеров).

EDIT: Я только что заметил, что в трассировке стека упоминается и mixin.Таким образом, он связан с геттером или сеттером, который определен в характеристике и используется в классе, или используется в характеристике.

РЕДАКТИРОВАТЬ 2: Все еще ведется расследование.Есть ли у вас перегрузочные геттеры / сеттеры для ленивых значений или геттеры / сеттеры, перегруженные ленивыми значениями?Или просто лень вальс на черты?В третьей строке трассы я увидел что-то, указывающее на ленивое значение.

Если вы найдете дополнительную информацию, попробуйте воспроизвести ее в небольшом случае, чтобы представить проблему.

1 голос
/ 13 ноября 2011

Если вы использовали управление исходным кодом и работали постепенно (вы имели , использовали управление исходным кодом и работали постепенно, да?), То вы уже знаете, что вызвало проблему - это последнее, что вы изменили.Поскольку вы работали в пошаговом режиме, это будет небольшим изменением, а поскольку вы использовали систему контроля версий, вы точно знаете, что это такое, потому что у вас есть полная история всего, что вы сделали.

Сократите это изменение до наименьшего изменения, которое все еще воспроизводит проблему (скорее всего, с помощью бинарной отбивной).Что-то в этом изменении будет «странным», и это то, что сбивает с толку компилятор.Найдите способ решить проблему, не используя эту «странную» вещь, и у вас есть обходной путь.

Но прежде чем сделать это, пожалуйста, сообщите об ошибке (любой случай, когда происходит сбой компилятора, определенноошибка), вместе с небольшим примером, который иллюстрирует это.

Если вы не работали в пошаговом режиме и не использовали контроль исходного кода, у вас есть намного более утомительное задание:

  1. Во-первых, определите, какой файл вызывает проблему (используйте двоичный код, чтобы сузить его, пока вы не определили один файл).
  2. Затем определите, какой бит этого файла вызываетпроблема (бинарное прерывание снова).
  3. Продолжайте бинарное измельчение, пока не получите одно простое изменение.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...