Зазор между двумя печатями в C ловится только пятиминутной сборкой, и на файлах self/ не ловится вовсе
Печать в C написана дважды — эталоном flang/src/emit/c.mjs и близнецом flang/self/emit-c.flang, — и расхождение между ними ловят два разных места. Быстрое (flang/test/self-emit-c.test.mjs, полторы минуты) сверяет их побайтово, но только на 30 программах stdlib, examples, core и на самом emit-c.flang. Медленное (flang/test/self-bootstrap.test.mjs, «шаги 2 и 3», от пяти до девяти минут) сверяет на ВСЁМ компиляторе — и только оно видит расхождение на файлах flang/self/.
Улика. Ветка work/pravyy-kray, коммит 6e476819: «шаги 2 и 3» покраснели с точным местом — compiler_flang.c, строка 132419, функция «Ветвь под границей» из flang/self/proof-kernel.flang. Эталон печатал там if (fl_t24906) { (хвостовая позиция: *result = …; return FL_OK;), близнец — fl_value fl_t24907 = fl_nothing(); (позиция выражения). Всё до этой строки совпадало побайтово, включая номера временных.
Почему быстрая сверка молчала. flang/self/proof-kernel.flang в её корпус не входит. Попытка внести — прогон упирается в предел шагов интерпретатора: «Идентификаторы для» исчерпала лимит шагов (200000000) за 57 секунд, потому что близнец печати гоняется НА ИНТЕРПРЕТАТОРЕ, а файл — шесть тысяч строк. То есть быструю сверку нельзя просто расширить: она упирается не в вкус, а в цену.
Чем воспроизводить не удалось. Шестнадцать проб на маленьких модулях — или в хвосте, или двух вызовов, или с содержит, шесть уровней вложенного если, цепочка пусть перед если не, разбор с записями, взаимная рекурсия из пяти функций — расхождения НЕ дали ни одна. Не дал его и срез из 47 моих функций, вынесенный в отдельный модуль с заглушками: там обе печати совпали побайтово. Значит зазор зависит от окружения функции в файле, а не от одной её формы, и малой пробой он не ловится.
Чем кончилось. Правка следующего коммита (5e64b9db, проверка «образец перевязал разбираемое имя») переписала ровно ту строку условия, и «шаги 2 и 3» позеленели: 29 из 29. Зазор не найден и не починен — он ОБОЙДЁН, и это надо знать: та же форма, написанная в flang/self/ снова, покраснеет снова, и покраснеет только через пять минут сборки.
Что из этого следует. Правя flang/self/*.flang, прогонять self-bootstrap.test.mjs целиком, а не только быстрые проверки: точка раскрутки (bootstrap/) сверяется побайтово всегда и дёшево, но она сверяет ПЕЧАТЬ ЭТАЛОНА с деревом, а не две печати между собой. Зелёная точка раскрутки не означает сошедшейся неподвижной точки.
Связано: right-edge-alone-closes-nothing, proof-words-live-on-two-surfaces-of-four