Skip to content

Implement canonical interface names in wit-component - #2622

Open
chenyan2002 wants to merge 17 commits into
bytecodealliance:mainfrom
chenyan2002:canon-ver-3
Open

Implement canonical interface names in wit-component#2622
chenyan2002 wants to merge 17 commits into
bytecodealliance:mainfrom
chenyan2002:canon-ver-3

Conversation

@chenyan2002

@chenyan2002 chenyan2002 commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #2556 and replaces #2602.

  • Add config flag emit_canonical_names in ComponentEncoder to emit canonical version.
  • When both implement and versionsuffix are present, the versionsuffix should refer to the version from implement, instead of the main package name.
  • Fixed a bug in merge_world_imports_based_on_semver that implements version is not updated during the merge.
  • Add CLI flag --emit-canonical-names to wasm-tools component new

During the transition period, upstream libraries, e.g., wac, can decode the original binary and re-encode with the emit_canonical_names flag enabled, so that we convert all binaries into their canonical encoding as a preprocessing step. Then wac can merge the interface via string matching directly.

@chenyan2002
chenyan2002 requested a review from a team as a code owner August 25, 2026 00:26
@chenyan2002
chenyan2002 requested review from dicej and removed request for a team August 25, 2026 00:26
Comment thread crates/wit-component/src/encoding/wit.rs Outdated
Comment thread src/bin/wasm-tools/component.rs Outdated
Comment thread src/bin/wasm-tools/component.rs Outdated
Comment thread crates/wit-parser/src/lib.rs Outdated
Comment thread crates/wit-parser/src/resolve/mod.rs Outdated
Comment thread crates/wit-component/src/encoding.rs Outdated
lukewagner pushed a commit to WebAssembly/component-model that referenced this pull request Aug 31, 2026
Tweak the string-splitting to more closely match the intent of versions
found in tooling, specifically:

* Document that build metadata (`+foo` in `0.0.1+foo`) is always split
  out and not part of the canonical name.
* Don't split out pre-release information since pre-release versions are
  incompatible with all other versions.

This additionally matches preexisting merging behavior in
`wit-component` as discovered in bytecodealliance/wasm-tools#2622
bail!(offset, "invalid interface version: {e}");
}
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could this validation move up to the above method? I think it'd be a bit clearer to perform this validation when implements is specified rather than deferring it to happen later here. That'd probably require validating the version_suffix field before implements and reorderin the above if statements, but that should be fine to do.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Neither way is perfect. We validate version_suffix with ComponentName here. Ideally, we would also validate the suffix with implements here. But moving up does make a smaller diff.

Comment thread crates/wit-component/src/encoding/wit.rs Outdated

fn encode_interface_export(
&mut self,
export_name: &str,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Right now this name logic is now split between the caller and the end of this function, but perhaps this parameter could be changed to ComponentExternName directly to avoid this duplication and instead have the logic in just one place?

external_id: resolve.external_id_value(key, item).map(|s| s.into()),
version_suffix: None,
let implements = resolve.implements_interface(key, item);
if canonical_names {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In a previous review I was curiuos if it would be possible to deduplicate the number of places that a canonical-names option was taken into account and a ComponentExternName were created. I count currently four different locations doing very similar things:

  1. here
  2. below in this file in for interface in interfaces
  3. in encode_interface_import in encoding.rs
  4. in encode_interface_export in encoding.rs (split across two functions)

Were you able to take a look and see if these locations could be unified? Is there perhaps one, or maybe two at most, helpers that could be used to construct these names?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will think about it tomorrow.

Comment thread crates/wit-component/tests/components/canonical-names/module.wat
Comment thread crates/wit-parser/src/resolve/mod.rs
Comment thread crates/wit-parser/src/resolve/mod.rs
@alexcrichton
alexcrichton removed the request for review from dicej September 5, 2026 04:13
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.

2 participants