Skip to content

recursion-cycle: de-conflate leaf-nominal identity from structural self-containment (un-spurious-Box leaf types; supersedes #5624) - #5686

Merged
briansrls merged 4 commits into
mainfrom
session/identity-deconflate
Jun 24, 2026
Merged

briansrls merged 4 commits into
mainfrom
session/identity-deconflate

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

What

De-conflate a leaf nominal's own identity from structural self-containment in the recursion-cycle dependency extraction, so opaque/alias/branded leaf types (Symbol, Char, Email, Url, Path-class, type parameters …) are no longer spuriously marked recursive and spuriously Box-wrapped in emitted Rust.

Root cause (by execution)

detect_type_cycles_kahn marks a type recursive if its deps contain its own name (self_ref). node_type_deps returns a leaf nominal's own name as a "dependency" (Symbol deps=[Symbol]) — because type Symbol (opaque), type Email = String (alias), type Char = Int where brand(...) (branded) all resolve to their own nominal identity. That self-name is the type's identity, not a structural dependency, so kahn over-marks every such leaf as recursive → spurious Box<…> in emit (the cargo-green E0308 class).

The kahn algorithm and import handling are correct; only the dependency-extraction input conflated identity with structural self-containment.

Fix

At the dependency-extraction call site (all_deps_map, both build_type_env copies): a binding whose resolved form is a bare leaf (NoConnective, 0 children) and whose deps are exactly [own_name] contributes no self-dependency. Genuine structural recursion (GrammarExpr, whose self-name comes from variant children) flows the unchanged structural path and stays marked. node_type_deps and the kahn algorithm are unchanged; no filter, no import-union, no resolve-stage change.

  • src/v1/04_infer.dag: helper deps_excluding_leaf_self + both fold sites (authority)
  • src/v1/stage0/src/v1_compiler_infer.rs: hand-mirror (both sites, inline)

Validation (by execution)

Apples-to-apples on identical sources (dsl-first compile-clean closure, --dependency-pool-index primary-precedence):

  • No net-new diagnostics: 486 files / 0 diagnostics before and after.
  • Box win: Box< 445 → 308 (−137); Box::new 258 → 123 (−135).
  • Smoking gun: 50 marks dropped — all leaf nominals + type-params; 0 newly marked; genuine recursion (GrammarExpr/GrammarProduction/GrammarRoot/Node/FreeMonoid/CoreNode) preserved.
  • target_model_runtime_import_repro 4/4 PASS (cross-module field access intact).
  • anthropic non-regression green; realization_reconcile green (no change — this fix is narrower than the abandoned v3 lever).
  • Red-on-revert: reverting restores the 445/258 boxes.

Supersedes #5624 (the v3 filter+union lever, refuted by execution).

🤖 Generated with Claude Code

Brian Searls and others added 4 commits June 23, 2026 22:21
…lf-containment

node_type_deps reports a leaf nominal's own identity (Symbol -> [Symbol]; opaque
`type Symbol`, alias `type Email = String`, branded `type Char = Int where brand`)
as a structural self-dependency, so detect_type_cycles_kahn's self_ref check
spuriously marks every leaf nominal recursive -> spurious Box<> in emitted Rust
(the cargo-green E0308 class). The kahn algorithm and import handling are correct;
only the dependency-extraction input conflated identity with structural
self-containment.

Fix at the all_deps_map call site (both build_type_env copies, + seed mirror):
a binding whose resolved form is a bare leaf (NoConnective, 0 children) and whose
deps are exactly [own_name] contributes no self-dependency. Genuine structural
recursion (GrammarExpr, whose self-name comes from variant children) flows the
unchanged structural path and stays marked. node_type_deps and kahn unchanged;
no filter, no import-union, no resolve-stage change.

Validated apples-to-apples on identical sources: Box< 445->308, Box::new 258->123,
0 diagnostics before and after (no net-new); target_model 4/4; anthropic
non-regression green; full v1-compiler-tests net-new=0 vs plain-main baseline.

Supersedes #5624 (v3 filter+union lever, refuted by execution).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@briansrls
briansrls merged commit aab132a into main Jun 24, 2026
2 checks passed
@briansrls
briansrls deleted the session/identity-deconflate branch June 24, 2026 02:46
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.

1 participant