Skip to content

Fix anomaly when alias-cloning a datatype type#1045

Merged
strub merged 1 commit into
mainfrom
fix-989
Jun 15, 2026
Merged

Fix anomaly when alias-cloning a datatype type#1045
strub merged 1 commit into
mainfrom
fix-989

Conversation

@strub

@strub strub commented Jun 15, 2026

Copy link
Copy Markdown
Member

Closes #989.

Problem

Overriding a datatype's type with another datatype via a plain alias (type ATy = ...) crashed during cloning:

theory Thy.
  type ATy = [constr].
  op useconstr = constr.
end Thy.

clone Thy as Thy1.

clone Thy as Thy2 with
  type ATy = Thy1.ATy,
  op useconstr <= Thy1.useconstr.

anomaly: File "src/ecUtils.ml", line 239 ... Assertion failed (an oget None).

Cause

When a datatype's type is overridden during cloning, the source datatype's constructors are not re-created in the clone (the new type isn't a Datatype). References to those constructors — e.g. in operator bodies — must therefore be redirected to the target datatype's constructors.

EcTheoryReplay.replay_tyd did exactly that, but only inside the Inline _ branch (<- / <=). For a plain alias override (=Alias), the source constructor paths were instead renamed to non-existent paths (Thy2.constr); force-reducing them in the operator-compatibility check tripped the oget None.

Fix

Lift the constructor-remapping out of the inline-only branch so it runs after the mode match, for every override mode. The substitution in scope at that point is already correct for both modes (rename for alias, add_tydef for inline).

Regression test added: tests/clone-datatype-alias.ec.

Notes / out of scope

This is a surgical fix; it will be subsumed by the planned refactor that introduces an explicit elaborator for derived objects (constructors, projectors, _ind/_case). Two related issues are left untouched as pre-existing and orthogonal (they reproduce on main, in both override modes):

  • Operator bodies that match on constructors (OP_Fix) still fail with CoreIncompatible under a datatype-type override — the remap only covers OP_Constr, not match bodies.
  • Polymorphic op overrides (op mk <= Thy1.mk with a type variable) fail with "operator body contains 0 type parameter instead of 1".

When a datatype type is overridden during cloning, the source
constructors are not re-created, so references to them (e.g. in
operator bodies) must be redirected to the target datatype's
constructors. This remapping only ran for inline overrides (<-/<=),
so a plain alias override (type t = ...) renamed the source ctors to
non-existent paths and tripped an oget None assertion.

Lift the constructor-remap out of the inline-only branch so it runs
for every override mode.
@strub strub added this pull request to the merge queue Jun 15, 2026
Merged via the queue into main with commit 36a709b Jun 15, 2026
19 checks passed
@strub strub deleted the fix-989 branch June 15, 2026 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anomaly caused by algebraic datatype shenanigans

2 participants