flang компилятор доказывает, что программа не зациклится 0.6.2 GitHub

Граница входа была долгом ПЕЧАТИ, а не вычитания в проверке: без неё напечатанный крейт Rust не собирается вовсе

Семь генераторов кода на самом flang (flang/self/emit-*.flang, все кроме emit-c.flang) не печатали блок ГРАНИЦЫ ВХОДА — таблицу объявленных типов параметров, по которой прогонщик сверяет пришедшее снаружи значение до вызова. В проверках это было записано как «долг эталона, названный и вычтенный» (flang/test/entry-debt.mjs): из вывода свидетеля блок вырезался, остаток сверялся побайтово, и сверка была зелёной.

Зелёной она была зря. Прогонщик каждой из этих целей зовёт таблицу по имени:

цельгде зовёт
rustflang/src/emit/rust/flang_cli.rs:458program::entry()
goflang/src/emit/go/flang_cli.go:269flang.Entry()
pythonflang/src/emit/python/flang_cli.py:166program.entry()
javaflang/src/emit/java/FlangCli.java:479program.entry()
csharpflang/src/emit/csharp/FlangCli.cs:542program.Entry()
elixirflang/src/emit/elixir/flang_cli.ex:421apply(module, :entry, [])
jsflang/src/emit/js/flang_cli.js:333program.$PROGRAM.entry

То есть вычитался не «лишний блок у свидетеля», а дыра в напечатанной программе. Прогонщик у крейта по умолчанию есть, и без блока программа не собирается.

Чем подтверждено, числом. Крейт, напечатанный из flang/stdlib/lists.flang, собран RUSTFLAGS='-D warnings' cargo build --offline дважды. Целиком — Finished dev profile ... in 0.80s, ноль замечаний. Он же с вырезанным блоком границы — error[E0425]: cannot find function 'entry' in module 'program', src/cli.rs:463, одна ошибка, сборки нет. Ветка rabota/vosem-rust.

Чем закрыто у Rust. «Печать границы входа Rust» и пять её спутников в flang/self/emit-rust.flang — 128 строк на flang, ни строки на другом языке. Таблица приезжает настройками, как и текст рантайма, по той же причине: решить, какой у параметра объявленный тип, — работа слоя типов, а не печати. Вычитание в flang/test/self-emit-rust.test.mjs снято целиком, и сверка идёт по ПОЛНЫМ файлам: побайтово совпало 108 из 108 программ репозитория, разошлось 0 (плюс 46 из 46 программ с числовой мерой).

Признак, по которому это ищется у остальных шести. Пересечь два множества: grep -c 'Граница входа' flang/self/emit-*.flang (сегодня: c — 2, rust — 2, js — 1, остальные пять — 0) и «зовёт ли прогонщик цели таблицу по имени» (таблица выше — зовут все семь). Пусто слева и не пусто справа — значит у этой цели эталон печатает программу, которая не соберётся с прогонщиком.

Чему учит. Вычитание в сверке — это утверждение «разница безобидна», и его надо ДОКАЗЫВАТЬ, а не объявлять. Здесь оно было объявлено в комментарии на двадцать строк, прожило от work/emit-entry-types до сегодня и всё это время прятало неработающую печать у семи целей из восьми. Проверка, которая нормализует расхождение, обязана нести рядом улику того, что нормализованное никому не нужно, — иначе она перестаёт сравнивать и продолжает зеленеть.

Чем ограничено. Закрыт долг у одной цели — rust. У go, java, python, csharp, elixir блок по-прежнему не печатается, и вычитание в их проверках стоит на месте. JavaScript не проверялся: у него блок — поле объекта, а не отдельное объявление, и «не соберётся» там не обязано значить то же самое.

Связано: checks-that-stopped-comparing, emitter-twin-gap-is-only-caught-by-a-five-minute-build, pulling-a-module-into-the-self-hosted-compiler-pays-for-meetings-not-size