Register enum defs reachable through ADT fields - #223
Draft
coord-e wants to merge 1 commit into
Draft
Conversation
`register_enum_defs` discovered the enums a body needs by visiting the types of
its local declarations, and a `TypeVisitor` descends into an ADT's generic
arguments only. An enum occurring solely as the field type of another ADT --
`struct Wrap { o: Option<i32> }`, or `enum Outer { X(Inner), Y }` -- was
therefore never registered, while the elaboration of the outer ADT does reach
it, so the lookup of its `EnumDatatypeDef` through `EnumDefProvider` unwrapped
a `None`.
Collect the enums with `EnumDefCollector`, which follows the structure the
elaboration follows: an ADT that is not translated as a model type is
elaborated into its fields, so the enums those fields mention are needed too.
Registering `Option` also exposed the sort side of the same gap. A datatype
sort that occurs only as the selector of another datatype -- the tuple that
`Wrap` elaborates to -- never reached the monomorphization in `FormatContext`,
and the emitted SMT-LIB2 referred to a sort it never declared. Close the sort
collection over the selectors of the datatypes being declared.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BFzi5Pc3p3DwocuhvTiVLK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #221.
Enum registration
basic_block::Analyzer::register_enum_defsdiscovered the enums a body needs by running aTypeVisitorover the types of its local declarations, andsuper_visit_withon anAdtdescends into that ADT's generic arguments only. An enum occurring solely as the field type of another ADT —struct Wrap { o: Option<i32> }, orenum Outer { X(Inner), Y }— was therefore never registered, while the elaboration of the outer ADT does reach it, so theEnumDefProviderlookup unwrapped aNone.EnumDefCollector(inrefine::template, next to theTypeBuilderit mirrors) replaces the inline visitor. It follows the structureTypeBuilder::buildfollows: an ADT that is not translated as a model type is elaborated into its fields — a struct into the tuple of its fields, an enum into the fields of its variants — so the enums those fields mention are needed as well. Model types keep their fields unvisited, since they are translated directly, and anelaborated_adtsset keeps recursive ADTs from looping.Undeclared sort
Registering
Optionwas not enough to make the by-value reproduction verify: the enum reachedchc::System::datatypes, but the emitted SMT-LIB2 still referred tostd.option.Option<Int>without declaring it.FormatContext::from_systemmonomorphizes a polymorphic datatype only for datatype sorts collected from the clauses, andOption<Int>occurs nowhere in them — the locals have the sort of the tupleWrapelaborates to, andOption<Int>appears only as that tuple's selector. Sort collection now runs to a fixpoint over the selectors of the datatypes being declared, so a sort reachable only through another datatype's field gets monomorphized and declared too.Checking
Every program in the issue — both by-value reproductions, the by-reference one, the nested-pattern program, and the two controls — now reports
safe. Both directions of the check still hold: withstruct Wrap { o: Option<i32> }, a body asserting the wrong value of the field reportsUnsatwhile the correct one passes.cargo test(316 ui tests, unit and doc tests),cargo clippy -- -D warnings, andcargo fmt --checkall pass. No test case is added, per the request.Generated by Claude Code