Skip to content

fix(types): preserve package-local bare type identity#2626

Open
slepp wants to merge 2 commits into
mainfrom
fix/2208-package-local-type-identity
Open

fix(types): preserve package-local bare type identity#2626
slepp wants to merge 2 commits into
mainfrom
fix/2208-package-local-type-identity

Conversation

@slepp

@slepp slepp commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • I bind a package-local bare type reference to its owning module-qualified identity, so same-named types in sibling modules cannot collapse onto the last-written bare registry key.
  • I carry the full dotted declaring-module path through stdlib visibility metadata, so private types remain accessible from their own nested module while cross-module checks still use canonical module identities.
  • I preserve existing owner-qualified type definitions against cross-module bare-key clobbering, while still allowing the owning module to refresh them during import-alias member re-resolution.
  • I keep local channel handle arity and trait Self substitution coherent after local names become qualified.
  • I added a nested private-local regression and strengthened the original collision regression to cover both import orders.

This takes over and completes @gertybotbot's work in #2619. Their original own-qualified binding and collision regression are preserved as an authored commit in this branch. Thanks to @gertybotbot for reporting #2208 and for the original fix.

Fixes #2208

Testing

  • hew check hew-types/tests/fixtures/net_parameter_surfaces_typecheck.hew
  • make hew-check-all (1,575 files; expected failure set matched)
  • cargo test -p hew-types
  • cargo test -p hew-hir
  • cargo check --workspace
  • Private-local regression verified to fail when the full-path visibility fix is reverted
  • Collision regression verified to fail when the own-qualified binding is reverted

gertybotbot and others added 2 commits July 11, 2026 15:07
…ntity (#2208)

A bare type reference inside a non-root module (e.g. a `Holder { w: Wrap }`
field whose `Wrap` is declared in the same module) resolved through the
`is_local` arm to the BARE `type_defs` key. That key is last-write-wins across
modules that declare the same bare name — `pre_register_type_decl` documents
the qualified alias as the authority — so when a sibling module declares its
own `Wrap`, the field silently bound to whichever module registered `Wrap`
last.

This is observable in a correctly-disambiguated program (contradicting the
issue's "unobservable" note): two package-local modules each with a divergent
`Wrap` + `Holder { w: Wrap }` mis-resolve one holder's field to the other
module's layout, surfacing as `no field `a_field` on type `Wrap` — help:
b_field`, and the winner flips with import order.

Fix: in the `is_local` arm, bind to the current module's OWN qualified identity
(`{short}.{name}`) when that key exists, mirroring the sibling
`published_bare_type_qualified` branch that already qualifies to dodge the same
bare-key collapse. `pre_register_type_decl` always seeds the qualified key
alongside the bare one, so non-colliding locals and root-module refs
(`current_module_short() == None`) resolve exactly as before.

Load-bearing regression `same_bare_name_member_field_binds_to_own_module_identity`
asserts each holder's `w` field carries its own module's `Wrap` identity; it
fails on revert (both collapse to the last-writer). Full hew-types (1665 lib +
integration) and hew-hir suites green; fmt + clippy(--tests) clean.
Carry full declaring-module paths through stdlib visibility metadata, preserve owner-qualified type definitions across bare-name collisions, and keep local handle and trait Self identities coherent after qualification. Add the nested private-local regression and exercise both #2208 import orders.
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.

Package-local same-bare-name type-body resolution collision (pre-existing, surfaced during #2202)

2 participants