Motoko: move `ByteBuf` and `Result` into `Types` so mixins can be siblings
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 21
- Forks
- 7
- Avg merge
- 10h 30m
- Merged PRs (30d)
- 5
Description
What we are asking for
Move ByteBuf and Result into mo:ic-vetkeys/Types, which already
exists. Nothing new, no rename.
Why it is a prerequisite, not a preference
Two Motoko mixins cannot both declare the same type. Today ByteBuf and
Result are declared inside the mixin
(ControlPlaneCanister.mo:88-91),
so any two mixins that both need them cannot be siblings:
// A.mo and B.mo, each with: public type ByteBuf = { inner : Blob };
composite.mo:5.11-5.12: type error [M0051], duplicate definition for type ByteBuf in block
Same error whether the declaration is public or not. This is why the
library composes as a chain today — ControlPlaneCanister declares both
and Canister declares neither, inheriting them through include. A chain
only yields prefixes: you can keep "everything up to enumeration" and own the
values; you cannot keep everything except vetKD.
So this blocks #443's ask 1 (define the composite in terms of includable
parts) outright. It is small, settled, and can land first.
Why Types rather than a new module
Types already holds AccessRights — a type that appears seven times in the
Candid — beside its internal operations vtable. Adding two more interface
types is not a change of character, and types.mo is where the Motoko
architecture guidance puts a central schema anyway.
A group then imports exactly one type module:
import EncryptedMaps "mo:ic-vetkeys/encrypted_maps/EncryptedMaps";
import Types "mo:ic-vetkeys/Types"; // ByteBuf, Result, AccessRights
The migration cost, which is not zero
Adopters currently write ByteBuf unqualified because the mixin declares it —
ic_vetkeys_encrypted_maps_custom_canister does. They would have to
qualify it, and specifically not alias it locally. A local alias looks
free and is not:
public type Result<Ok, Err> = Shared.Result<Ok, Err>; // compiles, service stays correct
It renames the generated binding's types — Result_2 → Result_1,
Result_11 → Result__1_3 — while the service itself is unchanged: we
resolved every alias transitively and compared all 29 methods, with 0
differing signatures. So the churn is invisible to a conformance check and
very visible in a diff of the committed declarations.
This is the trap the release note has to name, because "qualify, don't alias"
is not advice anyone derives on their own.
Worth a release note, and worth updating both custom-canister examples in the
same change.
We hit the collision only because we created a second Types locally; had
the library's own module held all three, there would have been nothing to
alias.
Split out of #443, where this was ask 5. #443's ask 1 depends on it.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at ControlPlaneCanister.mo lines 88-91 and the existing mo:ic-vetkeys/Types module to trace the ByteBuf and Result declarations and their consumers. Update the two custom-canister examples to qualify these types, add the release note warning to qualify rather than alias them, and verify the mixin composition and generated declarations remain correct.
Written by the indexing model from the issue text.
Assessment
- Domain
- backend-api-design
- Issue type
- Refactor
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100