migrating-to-moc-2
Migrating to moc 2
moc 2 is a major release of the Motoko compiler. It changes four things:
- Persistence. Actors are persistent by default. Enhanced orthogonal persistence (EOP) is the only memory model and the incremental GC the only collector.
- Strictness. Warnings for code that traps or silently does not do what it says are now errors, and a pattern must fit the type it matches.
- Syntax. A few moc 1 forms no longer parse (
a ??b, a branch glued to its condition,flexible). Several lighter forms are new and optional. - Flags. Every flag of a removed feature is rejected as an unknown option.
Most projects need a handful of edits, and the compiler names each one. This skill maps every diagnostic to its fix. The upstream moc 1 → 2 migration guide has longer explanations, and the release notes list each change per release.
First: is any canister still on classical persistence?
moc 2 cannot build a canister on classical (32-bit) persistence, but it can upgrade one to EOP. A deployed canister is classical if it was built with --legacy-persistence, with a non-incremental GC flag (--copying-gc, --compacting-gc, --generational-gc), or with a moc older than 0.15, where classical was the default.
- Move it to EOP: compile that one upgrade with
--enhanced-orthogonal-persistenceand without--enhanced-migration. The move is irreversible; later upgrades need neither flag. Without the flag the upgrade traps ("Detected implicit upgrade from classical orthogonal persistence to enhanced orthogonal persistence"); with--enhanced-migrationit traps too ("Cannot upgrade from classical orthogonal persistence with --enhanced-migration"). - Keep it classical: stay on moc 1.
A canister that moved to EOP with a moc older than 1.5.0 can trap on a later upgrade with cannot upgrade from an actor using enhanced migration to an actor not using enhanced migration. Run that one upgrade with graph-copy stabilization; the upstream EOP migration path has the steps.