Skip to content

Conversation

@ChrisPenner
Copy link
Member

@ChrisPenner ChrisPenner commented Dec 4, 2025

Overview

in #6007 I introduced checks to prevent creation of certain classes of problematic components for which there were multiple possible components for the same hash;

However in doing so, it also triggered failures where valid definitions contained structurally equivalent letrec-bindings

This change makes it so we only trigger the error on top-level bindings, not internal let-recs.

See https://www.notion.so/unisonweb/Cycle-Hashing-Issue-2bf5fbdd830d80c8b2ffe821c0f8638a?showMoveTo=true&saveParent=true for some more internal notes on the issue.

Implementation approach and notes

The original plan was to use IsTop from the ABT Term Functor to determine whether we were hashing the top-level cycle, however this didn't work in all cases because the V2 Term Functor doesn't have an IsTop, and adding one would affect the serialization format which is no good;

Instead I added an argument to doHashCycle for isTop, and set it to true on the initial call to hashComponents and False when we recurse.

I'm not 100% positive of the behaviour here, but it does seem to be working as expected in tests.

Test coverage

  • Added a new transcript for testing that we don't fail on internal cycles
  • Left existing transcript which asserts that we do fail on top-level cycles (when structurally equivalent)
  • Added a transcript testing that we do fail on structurally equivalent elements within structural data type cycles

Comment on lines 123 to 126
Constructors cs ->
-- Should constructors be considered top-level?
let (hashes, _) = hashCycle cs
in tag 2 : map hashed hashes
Copy link
Member Author

@ChrisPenner ChrisPenner Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aryairani Do I need to consider constructors as top-level? I think so, since constructor re-orderings would be problematic when there are external references in.

Copy link
Contributor

@aryairani aryairani Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think constructors can be part of cycles so I don't think it matters? Or am I forgetting something?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna merge it for now, but we can discuss soon

@ChrisPenner ChrisPenner force-pushed the cp/only-validate-top-level-bindings branch from 29af5ce to 1f4b70d Compare December 4, 2025 23:34
@ChrisPenner ChrisPenner marked this pull request as ready for review December 5, 2025 00:00
@aryairani aryairani merged commit a560274 into trunk Dec 5, 2025
31 checks passed
@aryairani aryairani deleted the cp/only-validate-top-level-bindings branch December 5, 2025 02:31
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.

3 participants