Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion dag/gunbc/recurring_failure_mode.dag

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions docs/design-failure-modes.md

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions fixtures/if_join_pool_binding/closure_with_collision.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module fixtures.if_join_pool_binding.closure_with_collision

// THE RED ARM. Entry here puts BOTH modules in one closure and the compile REFUSES at
// `declaring_module`'s if-expression:
//
// if branches resolve to incompatible types:
// Coproduct(PoolSpecimenShape) vs Product(PoolSpecimenSquare)
//
// The refusal names `declaring_module`, which neither declares nor imports the competing type --
// an innocent site. Note this module need not import the colliding SPELLING at all; importing any
// other member of `colliding_module` is enough, because pool MEMBERSHIP is the variable.
import fixtures.if_join_pool_binding.declaring_module { PoolSpecimenShape, pick_shape }
import fixtures.if_join_pool_binding.colliding_module { PoolSpecimenSquare }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Import a non-colliding sentinel in the perturbation fixture

This fixture claims to prove that merely adding colliding_module to the pool is sufficient and that the entry need not import the colliding spelling, but it imports and uses PoolSpecimenSquare directly, and that is the module's only declaration. Consequently the committed discriminator never exercises the stated “import any other member” case; add a differently named exported sentinel and use that to pull the module into the closure so the fixture actually isolates pool membership from importing the colliding declaration.

Useful? React with 👍 / 👎.


fn refusing_use(c: Bool) -> PoolSpecimenShape {
pick_shape(c: c)
}

fn foreign_square() -> PoolSpecimenSquare {
PoolSpecimenSquare { s: 3 }
}
11 changes: 11 additions & 0 deletions fixtures/if_join_pool_binding/closure_without_collision.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module fixtures.if_join_pool_binding.closure_without_collision

// THE POSITIVE CONTROL, AND IT IS WHAT MAKES THE RED ARM DISCRIMINATING RATHER THAN MERELY RED.
// Entry here reaches the SAME BYTES of `declaring_module` with `colliding_module` absent from the
// closure, and the compile reports 0 blocking errors. Without this arm a reader could not tell a
// refusal caused by pool membership from a refusal caused by the specimen being ill-typed.
import fixtures.if_join_pool_binding.declaring_module { PoolSpecimenShape, pick_shape }

fn accepting_use(c: Bool) -> PoolSpecimenShape {
pick_shape(c: c)
}
10 changes: 10 additions & 0 deletions fixtures/if_join_pool_binding/colliding_module.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module fixtures.if_join_pool_binding.colliding_module

// THE PERTURBATION, AND IT IS THE ONLY DIFFERENCE BETWEEN THE TWO CLOSURES. A standalone product
// spelled the same as an ARM of another module's coproduct. This module is not on
// `declaring_module`'s ancestor chain, does not import it, and is not imported by it.
//
// namespace-resolution-design.md section 13 (operator-ratified 2026-07-21, default
// NamespaceOnlyY) decides an off-chain candidate as ZERO-ON-CHAIN and therefore UnresolvedType.
// The type and variant-arm channel does not honour that: it binds here instead.
type PoolSpecimenSquare { s: Int }
20 changes: 20 additions & 0 deletions fixtures/if_join_pool_binding/declaring_module.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module fixtures.if_join_pool_binding.declaring_module

// THE SUBJECT. This module declares BOTH arms of its own coproduct and returns one arm per
// if-branch, which is a well-typed inhabitant of the declared return in every closure. Nothing
// here refers to any other module, and the file is BYTE-IDENTICAL across the two closures that
// disagree about it -- that invariance is the whole instrument.
//
// A coproduct ARM is pool-visible corpus-wide while NOT being a local binding under its own
// spelling, so `PoolSpecimenSquare` below misses local lookup and lands in the pool. When
// `colliding_module` is present it binds THERE, the arm stops widening to its owner coproduct,
// and the if-join then compares a widened arm against a bare product. Inside this module not even
// the unlisted-import advisory fires, because the spelling is in `source_visible_names` here --
// which is why the class is silent at the site that causes it.
type PoolSpecimenShape
= PoolSpecimenCircle { r: Int }
| PoolSpecimenSquare { s: Int }

fn pick_shape(c: Bool) -> PoolSpecimenShape {
if c { PoolSpecimenCircle { r: 1 } } else { PoolSpecimenSquare { s: 2 } }
}
Loading