Skip to content

chore - Unify symbol identity across import and package boundaries #699

@dannymeijer

Description

@dannymeijer

Area

  • Incan Language (syntax/semantics)
  • Compiler (frontend/backend/codegen)
  • Tooling (CLI/formatter/test runner)
  • Runtime / Core crates (stdlib/core/derive)
  • Documentation

Summary

Incan 0.3 exposed a recurring class of boundary-sensitive compiler defects: code that works locally changes behavior when the same symbol crosses an import, package, stdlib, decorator, static-initialization, or test-batch boundary.

The core problem appears to be that the compiler still carries several competing identities for the same source item: source spelling, local lowered name, canonical module path, exported/package identity, emitted Rust path, and synthetic test-runner harness identity. Those should be projections of one resolved symbol identity, but today some stages recompute or approximate them with strings and context-sensitive lookup.

This chore tracks a v0.4 architecture pass to make symbol identity first-class and make import/package/test boundaries behavior-preserving instead of semantic fault lines.

Recent motivating examples include public aliases, imported partial presets, decorator metadata, imported statics, package-boundary projections, and directory-batched inline tests.

Scope

  • In scope:
    • Define a single resolved symbol identity model for functions, methods, types, statics, aliases, partial presets, decorators, and exported package items.
    • Make local, imported, package-consumer, stdlib, and test-batch references use the same semantic identity instead of re-looking up by short name.
    • Separate source symbol identity from emitted Rust path selection.
    • Audit frontend/typechecker, IR lowering, metadata export/import, package manifests, stdlib loading, and test-runner batching for duplicate name-resolution paths.
    • Add import-boundary equivalence coverage for aliases, partials, decorators, statics, callable metadata, and inline tests.
    • Add package-boundary round-trip coverage for the same surfaces.
    • Document the intended symbol identity model for compiler contributors.
  • Out of scope:
    • Adding new language namespace features unless the audit proves the current model cannot express the intended behavior.
    • Reworking all Rust emission architecture unrelated to symbol identity.
  • Risks:
    • This touches high-traffic compiler paths and can regress default-argument filling, callable metadata, stdlib loading, and package exports if done as a large unverified rewrite.
    • The work should be staged behind focused invariants and equivalence tests rather than landed as a single broad refactor.

Plan

  1. Inventory every place that currently resolves a source item by short string, canonical path string, manifest export string, or emitted Rust path.
  2. Define the canonical symbol identity structure and projection rules for local source, imports, package exports, stdlib modules, and test harness modules.
  3. Move frontend/typechecker outputs toward carrying resolved symbol identities for value/type/static/callable references.
  4. Adjust IR lowering so call/static/type references preserve that identity and projected callable signatures/defaults.
  5. Adjust metadata export/import so aliases, partials, decorators, and statics round-trip without losing identity or projected surface.
  6. Adjust codegen so the emitter consumes resolved identities and only maps them to Rust paths; it should not rediscover semantics by bare name.
  7. Add equivalence tests comparing focused-file, directory-batch, package-producer, package-consumer, and stdlib-import behavior.
  8. Update contributor documentation with the rule: import boundaries may affect visibility and initialization timing, but not semantic identity.

Done when

  • Local and imported references to the same exported symbol use the same semantic identity and projected signature.
  • Aliases, partial presets, decorators, statics, callable metadata, and public package exports pass focused and imported/package-boundary equivalence tests.
  • incan test file.incn and incan test directory/ agree for inline-test symbol identity unless there is an explicit documented visibility difference.
  • The emitter no longer performs semantic lookup by short name when a resolved symbol identity should already be available.
  • Compiler contributor docs describe the identity model and the boundary invariants.
  • The v0.4 release notes can point to this work as a deliberate reduction in import-boundary behavioral drift.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions