Skip to content

RFC-010b: Полнота сопоставления с образцом (деконструкция вариантов и исчерпываемость) ​

Настоящий документ является под-RFC для RFC-010 (унифицированный синтаксис типов). Объявление вариантов, форма вызова конструкции и представление tagged union во время выполнения (включая порядок объявления variant_id — входной набор вариантов для проверки исчерпываемости в данном RFC) определены в разделе RFC-010 «Конструкция вариантов для типов в форме записи и sum type (авторитетное определение)»; настоящий RFC реализует зеркальную сторону: деконструкцию match и проверку исчерпываемости. Конструкция и деконструкция должны быть парными, поэтому они отнесены к одному RFC-010.

Исходный номер RFC-039 (составлен 2026-09-03); 2026-09-25 по решению владельца объединён в под-RFC RFC-010 и перенумерован в RFC-010b, отслеживающий issue остаётся #330.

Резюме ​

Расширение сопоставления с образцом в match с текущего «только литералы + подстановочный знак» до полных возможностей: шаблоны вариантов Union (включая привязку полезной нагрузки), шаблоны структур/кортежей, реализация в IR шаблонов Or и охранных выражений, а также проверка исчерпываемости (E1030/E1031 переходят от пустого зарезервированного кода к реальной эмиссии). Данный RFC является предварительным условием для направления развития Error { kind: ErrorKind, message } (раздел развития в RFC-013 «Согласованность значений ошибок и сквозных кодов во время выполнения»), но мотивация самостоятельна — сопоставление с образцом представляет собой общую возможность языка, обслуживающую все типы с вариантами.

Мотивация ​

Текущее состояние — эмпирические данные (2026-09-03, код v0.7.12) ​

  1. На уровне IR реально реализованы только шаблоны литералов. AST уже определяет полный набор шаблонов (src/frontend/core/parser/ast.rs:578: Wildcard / Identifier / Literal / Tuple / Struct / Union / Or / Guard), парсер способен разбирать шаблоны вариантов вида ok(v), err(e) (Pattern::Union); однако генерация IR (начиная с src/middle/core/ir_gen.rs:5330) реализует только ветку Literal, остальные шаблоны попадают в заглушку — загружается константа 0 для участия в сравнении на равенство, что никогда не приводит к совпадению; при этом если scrutinee в точности равен 0, происходит ошибочное совпадение с веткой-заглушкой (потенциально некорректное поведение).
  2. Пример match ok(v)/err(e) в stdlib.md — бумажная возможность. Синтаксис деконструкции вариантов, приведённый в документе спецификации (§1.3 Result), фактически не работает; реализация оператора ? не проходит через десахаризацию match, что маскирует это обстоятельство. В тестовом корпусе нет ни одного случая деконструкции вариантов (match.yx / pattern_matching.yx покрывают только литералы и подстановочный знак).
  3. Проверка исчерпываемости висит в воздухе. E1030 (Pattern non-exhaustive), E1031 (Unreachable pattern) зарегистрированы в таблице кодов, но не имеют точек эмиссии — семантика match не определена.
  4. Развитие обработки ошибок заблокировано. Значение Error во время выполнения в настоящее время использует строковые коды {code, message} в качестве единственного программируемого контракта для различения (RFC-013); структурированное моделирование (match e.kind { file_not_found(path) => ... }) зависит от деконструкции вариантов и привязки полезной нагрузки из данного RFC.

Цели проектирования ​

  • Деконструкция вариантов пригодна к использованию: деконструкция match r { ok(v) => ..., err(e) => ... } и пользовательских наборов вариантов (sum type в стиле записи) семантически согласована по трём путям выполнения.
  • Исчерпываемость надёжна: E1030/E1031 эмитируются реально, пропуск ветки в match является ошибкой компиляции.
  • Заглушки удалены: исключение поведения-заполнителя «загрузка 0 никогда не совпадает / совпадает ошибочно»; неподдерживаемые шаблоны должны порождать ошибку на этапе компиляции, а не молча приводить к неверному выполнению.

Предложение (уровень каркаса, подлежит наполнению) ​

ВозможностьОписание
Шаблоны вариантов UnionVariantName / VariantName(binding) — совпадение + привязка полезной нагрузки в область видимости ветки
Шаблоны Struct / TupleРеализация шаблонов полей и кортежей (AST уже имеется, IR дополняется)
Шаблон Or и GuardПорядок вычисления и правила привязки для p1 | p2 и p if cond
Проверка исчерпываемостиE1030 — пропуск ветки, E1031 — недостижимость, область покрывает набор вариантов (Result/Option в настоящее время относятся к core; проверка не зависит от принадлежности, см. RFC-011b этап 2 — перенос в std)
Уточнение семантики шаблона IdentifierНеобходимо определиться: голый идентификатор в текущем синтаксисе — это привязка или сравнение вариантов (связь с подстановочным знаком _)

Открытые вопросы ​

  • [ ] Шаблон Identifier: привязка новой переменной или сопоставление с существующим значением? (Семантика Rust vs сложившееся поведение в корпусе YaoXiang)
  • [ ] Границы применимости исчерпываемости: как наборы вариантов, возвращаемые динамическим импортом или методами интерфейса, участвуют в проверке исчерпываемости?
  • [ ] Нужен ли атрибут уровня non_exhaustive (влияет на радиус разрушения расширений наборов вариантов std для пользовательских match)?
  • [ ] Должна ли ошибка компиляции предшествовать переходному периоду перед исправлением ошибочного совпадения заглушки при загрузке 0?

Связанные документы ​

  • Раздел развития в RFC-013 «Согласованность значений ошибок и сквозных кодов во время выполнения» (Error { kind, message } зависит от данного RFC)
  • RFC-036 модель тестирования (синтаксис сопоставления при проверке утверждений для ветвей ошибок)
  • Закрытые случаи неприменимы; данный RFC представляет собой дополнение возможностей, а не исправление дефекта