Skip to content

csharp: omit version namespace segment when package is unambiguous (#1078)#1635

Open
sano-suguru wants to merge 1 commit into
bytecodealliance:mainfrom
sano-suguru:csharp/version-ns-only-when-ambiguous
Open

csharp: omit version namespace segment when package is unambiguous (#1078)#1635
sano-suguru wants to merge 1 commit into
bytecodealliance:mainfrom
sano-suguru:csharp/version-ns-only-when-ambiguous

Conversation

@sano-suguru

@sano-suguru sano-suguru commented Jun 13, 2026

Copy link
Copy Markdown

Ports the pkg_has_multiple_versions guard from the C generator (crates/c/src/lib.rs, interface_identifier) to the C# backend, closing #1078.

What changes

Previously the C# generator unconditionally appended a version segment to the namespace of every versioned WIT package:

my.dep.v0_1_0.wit.imports.a.Ia   // always, even when only one version exists

After this change the segment is only emitted when the same package namespace:name appears at more than one version in the Resolve — the only situation where omitting it would cause a collision:

my.dep.wit.imports.a.Ia          // single version → no segment
my.dep.v0_1_0.wit.imports.a.Ia   // coexists with v0_2_0 → segment kept

The guard logic is identical to the C backend's. The mangling format intentionally differs by design: C# emits v{major}_{minor}_{patch}. while C uses a trailing-underscore snake-case segment.

Tests

  • Unit tests on interface_name assert the generated namespace directly: the segment is dropped for a single-version package and kept when two versions coexist. I verified they fail if the guard is reverted to the unconditional form, so they lock the behavior (not just compilation) and run on every platform without the dotnet toolchain.
  • Codegen fixture tests/codegen/single-version-package (one versioned import, single version in the Resolve) builds the drop path across all backends, alongside the existing multiversion fixture (two versions of the same package) which guards the must-keep path.

C# codegen build tests don't run on my machine (macOS), so the dotnet build step is left to CI; cargo build and the unit tests pass locally.

Design decision

I asked on the issue whether this should be a silent default or gated behind a flag. @yowl preferred the default/no-flag approach for consistency with the C backend (#1078 (comment)). This changes generated C# namespace names for single-version packages — a breaking change that's acceptable pre-1.0 per that discussion.

@sano-suguru sano-suguru force-pushed the csharp/version-ns-only-when-ambiguous branch from 4bf5825 to 8c48205 Compare June 13, 2026 13:19
Port the `pkg_has_multiple_versions` guard from the C generator
(crates/c/src/lib.rs, `interface_identifier`) to the C# backend.

Previously the C# generator unconditionally appended a version segment
to the namespace of every versioned package (e.g. `my.dep.v0_1_0`).
Now the segment is emitted only when the same package namespace+name
appears at more than one version in the Resolve — i.e. when
omitting it would cause a name collision.

The guard logic is identical to the C backend's. The mangling format
intentionally differs: C# emits `v{major}_{minor}_{patch}.` while C
uses a trailing-underscore snake-case segment.

Tests:
- Unit tests on `interface_name` assert the namespace directly: the
  segment is dropped for a single-version package and kept when two
  versions coexist (verified to fail if the guard is reverted).
- A `tests/codegen/single-version-package` fixture (one versioned
  import, single version) builds the drop path across all backends,
  alongside the existing `multiversion` fixture (two versions).

Closes bytecodealliance#1078
@sano-suguru sano-suguru force-pushed the csharp/version-ns-only-when-ambiguous branch from 8c48205 to 23e4c85 Compare June 14, 2026 03:07
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