Skip to content

Conversation

@luc-blaeser
Copy link
Contributor

@luc-blaeser luc-blaeser commented Sep 5, 2025

Compromise for stable functions PR (#4789) for the sake of 100% backwards-compatibility.

  • Requires explicit persistent modifier on functions and classes to make feasible for EOP.
  • Changing name from stable to persistent for EOP.
  • Fully compatible with Motoko core library and other existing Motoko code.

Persistent Functions, Persistent Objects, and Persistent Classes

Functions, objects, and classes can also be persisted with enhanced orthogonal persistence, i.e. they been used in Motoko's persistent actor variables (aka stable variables in legacy mode).

Note: This is not supported with classical persistence.

With this, the only non-persistent (non-stable) values remain to be lambdas, async handles (aka continuations, futures), local async function references, and errors.

Example

With this, the following program can then used for orthogonal persistence. For this example, you need a specific core library version, which contains extensions of persistent object-oriented data structures.

import Map "mo:core/object-oriented/Map";
import Nat "mo:core/Nat";

persistent actor {
  let map = Map.Map<Nat, Text>(Nat.compare);

  public func main() : async () {
    assert map.isEmpty();
    map.add(1, "One");
    assert map.get(1) == ?"One";
    map.remove(1);
    assert map.get(1) == null;
  }
};

Persistent Modifier

A persistent modifier can be applied to functions, classes, and function types, as prerequisite to save functions as part of enhanced orthogonal persistent.

persistent function:

persistent func tick() { ... }

persistent class:

persistent class Clock() {
  public func tick() { ... }; // implicitly `persistent`
};

Functions (methods) of a persistent class are implicitly declared persistent.

persistent function types:

type Comparison<T> = persistent (T, T) -> Order.Order`

A persistent function implicitly has a corresponding persistent function type.

Persistent Functions and Persistent Scopes

A persistent function is a function that is declared persistent and occurs in a persistent scope.

A persistent scope is:

  • the main actor,
  • an actor class,
  • an imported module,
  • a nested module in a persistent scope,
  • a persistent function in a persistent scope,
  • a persistent class in a persistent persistent scope,
  • a method in a persistent class in a persistent scope, or,
  • a named object in a persistent scope.

Restrictions

Persistent functions anc classes cannot be anonymous.

Persistent functions capture only local variables of surrounding functions/classes/objects (closure) if they are of a stable type.
This restriction does not apply to immutable variables (let) and actor variables.

Generic type parameters of persistent functions and persistent classes are bounded to stable types.

Persistent Function Types

A persistent function type is also a stable type. Thus, a persistent function has a stable type.

A persistent function type is a sub-type of a non-persistent function type with type-compatible signature, i.e. persistent X' -> Y <: X -> Y' for X' <: X and Y' :< Y.

Upgrades of Persistent Functions

Persistent functions are upgraded as follows:

  • All persistent functions that are reachable from persistent actor variables are considered alive.
  • Each alive persistent function must have a matching declaration in the new program version.
  • Persistent functions match between program versions if they have an equal fully qualified name.
  • For matching functions, the function type of the new version must be compatible to the previous version (super-type).
  • For matching functions, the closure type in the new version must be compatible with the previous version, see below.

All other functions, such as e.g. functions that are not declared persistent, functions in a unnamed objects, functions in a non-persistent class, or functions in a lambda are transient functions.

Persistent Closures

The closures of persistent functions are represented in a portable format with the following clearly defined binding of captured variables:

  • Local variables (var) are captured by name.
  • Parameters are captured by position (also considering nested functions).

This offers flexibility for changes of persistent closures in new program versions:

  • New program version can capture less variables/parameters in persistent functions.
  • One can rename parameters even if they are captured by persistent functions.

On a persistent function upgrade, the closure type of the persistent function must remain compatible:

  • The new version of the persistent function does not capture more variables/parameters than the previous version.
  • The captured variable in the new version is a valid super-type of the previous version.

Specific aspects apply to generic types used in a persistent closure:

  • Generic types used for captured variables must match the previous declaration order (e.g. one cannot swap generic types).
  • The generic type bounds must remain compatible.
  • However, generic types do not need to be reified, see the reasoning in generics in persistent closures.

Runtime System Design

Function references are encoded by a function id in the following representation:

  • Persistent function id, encoded as non-negative number:
    A persistent function reference that stays invariant across upgrades.
  • Transient function id, encoded as negative number:
    A transient function reference that is invalidated on upgrade.

Each program version defines a set of named local functions that can be used as persistent function references. Each such function obtains a persistent function id on program initialization and upgrade. If the persistent function was already declared in the previous version, its function id is reused on upgrade. Thereby, the compatibility of the function type and closure type are checked. Otherwise, if it is a new persistent function, it obtains a new persistent function id, or a recycled id.

The runtime system supports persistent functions by two mechanisms:

  1. Persistent virtual table for persistent function calls:

    The persistent virtual table maps persistent function ids to Wasm table indices, for supporting dynamic calls of persistent functions. Each entry also stores the hashed name of the persistent function to match and rebind the persistent function ids to the corresponding functions of the new Wasm binary on a program upgrade. Moreover, each entry also records the type of the closure, referring to the persistent type table. The table survives upgrades and is built and updated by the runtime system. To build and update the persistent virtual table, the compiler provides a persistent function map, mapping the hashed name of a potentially persistent function to the corresponding Wasm table index, plus its closure type pointing to the new type table. For performance, the persistent function map is sorted by the hashed names.

  2. Function literal table for materializing persistent function literals:

    As the compiler does not yet know the function ids of persistent function literals/constants, this table maps a Wasm table index of the current program version to a persistent function id. The function literal table is re-built on program initialization and upgrade. When a persistent function literal is loaded, it serves for resolving the corresponding function id and thus the persistent function reference. The table is discarded on upgrades and (re-)constructed by the runtime system, based on the information of the persistent function map.

The runtime system distinguishes between transient and persistent function references by using a different encoding. This is to avoid complicated conversion logic been inserted by the compiler when a persistent function reference is assigned to transient reference, in particular in the presence of sharing (a function reference can be reached by both a persistent and transient function type) and composed types (function references can be deeply nested in a composed value that is assigned).

Compatibility Check

A persistent function compatibility check is performed by the runtime system on upgrade.

  • It checks for a matching function in the new version.
  • The function type compatibility is implicitly covered by the upgrade memory compatibility check, since the persistent function in use needs to be reachable by the persistent actor type.
  • The closure compatibility is additionally checked for each mapped persistent function. This covers all captured variables of the persistent function. This check is supported by the information of the persistent virtual table and the persistent function map.

Transient function references are represented as negative function ids determining the Wasm table index, specifically -wasm_table_index - 1.

Garbage Collection

The runtime systems relies on a dedicated garbage collector of persistent functions:

  • On pre-upgrade, the runtime systems determines which persistent functions are still alive, i.e. transitively reachable from persistent actor variables.
  • Only those alive persistent functions need to exist in the new program version.
  • All other persistent functions of the previous version are considered garbage and their slots in the virtual table can be recycled.
  • For efficiency, the GC is type-directed such that it only selectively traverses fields that may lead to persistent function type. Note: Same objects may be revisited if appearing by a different static type.

Garbage collection is necessary to allow programs to use persistent classes and persistent functions in only transient contexts or not even using imported persistent classes or functions. Moreover, it allows programs to drop persistent functions and classes, if they are no longer used for persistence.

The runtime system reports the fully qualified name of missing persistent functions (not only the internal name hash).

@luc-blaeser luc-blaeser requested a review from a team as a code owner September 5, 2025 15:13
@luc-blaeser luc-blaeser changed the title Stable Functions Weakened Stable Functions Softened Sep 8, 2025
* Allow persistent function calls during migration

Without use-before-define

* Add test case

* Appease the formatter

* Update test_recovery.ml

* Adjust test output

* Update variance.tc.ok

* Adjust tests
@crusso
Copy link
Contributor

crusso commented Sep 11, 2025

It's probably quicker for me to ask than read the code:
What happens to the classical compiler when it imports the persistent core library? Is the code accepted but persistent types aren't stable or can it just not use the modified core library?

luc-blaeser and others added 2 commits September 12, 2025 14:45
* chore: daily `flake.lock` update (#5353)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
as defined in [.github/workflows/update-flake-lock.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/16510781409/attempts/1:

```
Flake lock file updates:

• Updated input 'nix-update-flake':
    'github:Mic92/nix-update/a96a5c23bf09c2b3c295b789a2fd40e97f24e75c?narHash=sha256-SxTOXG/enF0ALdAciJEzDyUcrGP/FcWnT4NMTdfIDOo%3D' (2025-07-21)
  → 'github:Mic92/nix-update/65663d259920796fc6845d700cc44afa23a697ec?narHash=sha256-xQp4aaSLuk0RNbEo5xriA1r9/QzGxoZzvX2ggDWjgPU%3D' (2025-07-24)
```

* chore: Releasing 0.15.0 (#5356)

* chore: fix test (#5357)

see #5275 (comment)
this was a pilot error :-(

A minor, but confusing one...

* chore: daily `flake.lock` update (#5358)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
as defined in [.github/workflows/update-flake-lock.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/16534038002/attempts/1:

```
Flake lock file updates:

• Updated input 'candid-src':
    'github:dfinity/candid/dcf91291a7690e3da7a2ce2b8198ba17950fdeb7?narHash=sha256-XaG2HCTLPD1Pv2LjK1TaVnqDFyEWc7C6cydLjqui2/g%3D' (2025-07-21)
  → 'github:dfinity/candid/bc889594e3a4f1b4d563c6eb5c652b720b77a19c?narHash=sha256-UwaSnXapyFg8aA5LeD6pAZtZNDg55JuJP4qtrtnsF5U%3D' (2025-07-25)
• Updated input 'nix-update-flake':
    'github:Mic92/nix-update/65663d259920796fc6845d700cc44afa23a697ec?narHash=sha256-xQp4aaSLuk0RNbEo5xriA1r9/QzGxoZzvX2ggDWjgPU%3D' (2025-07-24)
  → 'github:Mic92/nix-update/5fce80c5e40a029269cd515ebd9ed3ebcf5d2701?narHash=sha256-LrjF/8LDsZF3Xh1R4u6xfBEMwz0TZMyU82VUJvwD4/c%3D' (2025-07-25)
• Updated input 'nix-update-flake/treefmt-nix':
    'github:numtide/treefmt-nix/421b56313c65a0815a52b424777f55acf0b56ddf?narHash=sha256-tzbhc4XttkyEhswByk5R38l%2BztN9UDbnj0cTcP6Hp9A%3D' (2025-07-20)
  → 'github:numtide/treefmt-nix/2673921c03d6e75fdf4aa93e025772608d1482cf?narHash=sha256-Bv9h1AJegLI8uAhiJ1sZ4XAndYxhgf38tMgCQwiEpmc%3D' (2025-07-25)
```

* chore: update release instructions for 0.15 (and on) (#5355)

More robust release instructions that allow major, minor and patch version bumps.

I've tested the instructions when releasing 0.15.0

* chore: daily `flake.lock` update (#5360)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
as defined in [.github/workflows/update-flake-lock.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/16545410914/attempts/1:

```
Flake lock file updates:

• Updated input 'motoko-base-src':
    'github:dfinity/motoko-base/818c032d26492f33f2fce59b40bfced822b315d0?narHash=sha256-hoxHiPFoD84luShzvnFqsvZZbTkireKPzhbcbllL7Z0%3D' (2025-07-01)
  → 'github:dfinity/motoko-base/120293a8cf0d3a61dbfd07d6cb0380a59a154179?narHash=sha256-0Drg4NK0rbGKbphTd2TgBOWLJoKRgV1LB8VXV4IqQnE%3D' (2025-07-26)
```

* chore: daily `flake.lock` update (#5364)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
as defined in [.github/workflows/update-flake-lock.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/16583480894/attempts/1:

```
Flake lock file updates:

• Updated input 'candid-src':
    'github:dfinity/candid/bc889594e3a4f1b4d563c6eb5c652b720b77a19c?narHash=sha256-UwaSnXapyFg8aA5LeD6pAZtZNDg55JuJP4qtrtnsF5U%3D' (2025-07-25)
  → 'github:dfinity/candid/e311782e9c9a93bbce09319ee0cb090ff05ac4bb?narHash=sha256-N/qkmE7ePx0qtxfjAnWYQSBKY/VNgKyo%2BilBbnXNDnQ%3D' (2025-07-28)
```

* feat: enable unqualified import of types (#5056)

## Overview

Allows pattern matching on type fields of modules and objects.

```motoko
import { type Result } "mo:base/Result";

func parse(input : Text) : Result<Nat, Text> {
  ...
}

// More contrived example

func example() {
  class Example() {
    public type T = Text;
  };
  let ex : Example = Example();
  let { type T } = ex;
  let x : T = "Hello";
};
```

## Design considerations

The current implementation does not require specifying type parameters on the type field pattern:

```motoko
import { type Result } "...";
// As opposed to:
import { type Result<Ok, Err> } "...";
```

The more conservative choice would be to require to specify the parameters and their bounds, but so far I haven't come up with an example where this is a problem. We might want to require it anyway, as it would be a breaking change to require them at a future time.

At the moment the implementation only resolves these type fields patterns on `let`'s (and imports), and requires a restricted "value path" on the rhs of the let. We should be able to relax these restrictions in the future, but for now this lets us cover the important use-cases while keeping implementation complexity down. Relaxing these restrictions would be a non-breaking change.

## Testing

I added a few test cases to the test suite and made sure this continues to compile the "big package set".

Ran a couple manual tests for candid generation, and everything seemed to be fine.

## Reviewer notes

There are a few places with NOTE or TODO comments left, I'd like to discuss those during the review.

* bugfix: issue 5336 (#5367)

Importing a `persistent` actor class would fail and report that the actor class must be declared `persistent` even though it was.

The problem is that the translation from ast to compilation unit and back again wasn't properly preserving the persistent annotation.

Also fixes another lurking bug in the parser that would be revealed when we turn on --default-persistent-actors.

Fixes #5336

* chore: daily `flake.lock` update (#5368)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
as defined in [.github/workflows/update-flake-lock.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/16610457683/attempts/1:

```
Flake lock file updates:

• Updated input 'candid-src':
    'github:dfinity/candid/e311782e9c9a93bbce09319ee0cb090ff05ac4bb?narHash=sha256-N/qkmE7ePx0qtxfjAnWYQSBKY/VNgKyo%2BilBbnXNDnQ%3D' (2025-07-28)
  → 'github:dfinity/candid/bc3e6802c153eb9e9d8fd5f383b8d4ea9e6b5b87?narHash=sha256-S8cTIV/pGur2n5UJhUHmEJbjtO1xnpnvkksXHvKXtGM%3D' (2025-07-29)
• Updated input 'nix-update-flake':
    'github:Mic92/nix-update/5fce80c5e40a029269cd515ebd9ed3ebcf5d2701?narHash=sha256-LrjF/8LDsZF3Xh1R4u6xfBEMwz0TZMyU82VUJvwD4/c%3D' (2025-07-25)
  → 'github:Mic92/nix-update/837d91abbef68e95a54107ccc6f0ecd597c34002?narHash=sha256-nsN5b1JgbnqAR6B3m98aPQjOWTQ4jjbM5sSb1dtvIoU%3D' (2025-07-29)
• Updated input 'nix-update-flake/treefmt-nix':
    'github:numtide/treefmt-nix/2673921c03d6e75fdf4aa93e025772608d1482cf?narHash=sha256-Bv9h1AJegLI8uAhiJ1sZ4XAndYxhgf38tMgCQwiEpmc%3D' (2025-07-25)
  → 'github:numtide/treefmt-nix/6b9214fffbcf3f1e608efa15044431651635ca83?narHash=sha256-8rkd13WfClfZUBIYpX5dvG3O9V9w3K9FPQ9rY14VtBE%3D' (2025-07-29)
```

* doc: Changelog++ (#5369)

* chore: Releasing 0.15.1 (#5371)

* chore: daily `flake.lock` update (#5373)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
as defined in [.github/workflows/update-flake-lock.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/16636760534/attempts/1:

```
Flake lock file updates:

• Updated input 'motoko-base-src':
    'github:dfinity/motoko-base/120293a8cf0d3a61dbfd07d6cb0380a59a154179?narHash=sha256-0Drg4NK0rbGKbphTd2TgBOWLJoKRgV1LB8VXV4IqQnE%3D' (2025-07-26)
  → 'github:dfinity/motoko-base/d158ab06d3c6be709d67e181dcf6a00335c76d79?narHash=sha256-T8nlv%2BNGUTHKlH/qPvNBMv0DTG2s6H0yrXu5Aj0ZVg8%3D' (2025-07-30)
```

* avoid JS 32-bit int limitiation when compiling to 64-bit (#5375)

* chore: daily `flake.lock` update (#5376)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
as defined in [.github/workflows/update-flake-lock.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/16687798697/attempts/1:

```
Flake lock file updates:

• Updated input 'nix-update-flake':
    'github:Mic92/nix-update/837d91abbef68e95a54107ccc6f0ecd597c34002?narHash=sha256-nsN5b1JgbnqAR6B3m98aPQjOWTQ4jjbM5sSb1dtvIoU%3D' (2025-07-29)
  → 'github:Mic92/nix-update/041496ef081c84c633ab04a9171c6addfc2d4e9d?narHash=sha256-sgSffk3wWQQuezIHORU9EFY7IajOhQm/DlHps%2BSkMAI%3D' (2025-08-02)
• Updated input 'nix-update-flake/flake-parts':
    'github:hercules-ci/flake-parts/644e0fc48951a860279da645ba77fe4a6e814c5e?narHash=sha256-TVcTNvOeWWk1DXljFxVRp%2BE0tzG1LhrVjOGGoMHuXio%3D' (2025-07-21)
  → 'github:hercules-ci/flake-parts/67df8c627c2c39c41dbec76a1f201929929ab0bd?narHash=sha256-XKqDMN1/Qj1DKivQvscI4vmHfDfvYR2pfuFOJiCeewM%3D' (2025-08-01)
• Updated input 'nix-update-flake/treefmt-nix':
    'github:numtide/treefmt-nix/6b9214fffbcf3f1e608efa15044431651635ca83?narHash=sha256-8rkd13WfClfZUBIYpX5dvG3O9V9w3K9FPQ9rY14VtBE%3D' (2025-07-29)
  → 'github:numtide/treefmt-nix/58bd4da459f0a39e506847109a2a5cfceb837796?narHash=sha256-ONcNxdSiPyJ9qavMPJYAXDNBzYobHRxw0WbT38lKbwU%3D' (2025-08-01)
```

* chore: daily `flake.lock` update (#5378)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
as defined in [.github/workflows/update-flake-lock.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/16737374202/attempts/1:

```
Flake lock file updates:

• Updated input 'candid-src':
    'github:dfinity/candid/bc3e6802c153eb9e9d8fd5f383b8d4ea9e6b5b87?narHash=sha256-S8cTIV/pGur2n5UJhUHmEJbjtO1xnpnvkksXHvKXtGM%3D' (2025-07-29)
  → 'github:dfinity/candid/7e1bd3b1ecde4163b86a231291ec7e5ad1250245?narHash=sha256-NQ75oLsUPfmbkPIc8saezuwvuizGF%2BOm02nLAxljLT4%3D' (2025-08-04)
• Updated input 'nix-update-flake':
    'github:Mic92/nix-update/041496ef081c84c633ab04a9171c6addfc2d4e9d?narHash=sha256-sgSffk3wWQQuezIHORU9EFY7IajOhQm/DlHps%2BSkMAI%3D' (2025-08-02)
  → 'github:Mic92/nix-update/a64b359d05a60a11701724b5a8090556eac1b5da?narHash=sha256-oibBkZ7JxVVJSnabHGB0XNwJiYJiAdfUhp7hxTv8ArY%3D' (2025-08-04)
```

* chore: daily `flake.lock` update (#5380)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
as defined in [.github/workflows/update-flake-lock.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/16764421262/attempts/1:

```
Flake lock file updates:

• Updated input 'nix-update-flake':
    'github:Mic92/nix-update/a64b359d05a60a11701724b5a8090556eac1b5da?narHash=sha256-oibBkZ7JxVVJSnabHGB0XNwJiYJiAdfUhp7hxTv8ArY%3D' (2025-08-04)
  → 'github:Mic92/nix-update/09aadb5d6d9e1fc57df0b61def4bdd8b43ea47a1?narHash=sha256-zumHGR/7NqlkSi8W7Vvdka/l/8x1aenpINg2jqepyeo%3D' (2025-08-05)
• Updated input 'nix-update-flake/flake-parts':
    'github:hercules-ci/flake-parts/67df8c627c2c39c41dbec76a1f201929929ab0bd?narHash=sha256-XKqDMN1/Qj1DKivQvscI4vmHfDfvYR2pfuFOJiCeewM%3D' (2025-08-01)
  → 'github:hercules-ci/flake-parts/7f38f25a44023a21a504bd3fd9d4f41c4a39f55c?narHash=sha256-3e4wHzNwTMg7GaeLH9A091DMaO9AfFxUjpfqbddCUeo%3D' (2025-08-05)
```

* chore: fix warnings in moc_js (#5386)

Address the following mysterious js_of_ocaml warnings:

js_of_ocaml int are 32-bit and these constants exceed that (but do fit into 63-bit) Ocaml ints.

```
crusso@crusso-Virtual-Machine:~/motoko/src$ make moc.js
source_id/gen.sh
dune build --profile=release --profile=release _build/default/js/moc_js.bc.js
Warning: integer overflow: integer 0x29e8d60800 (180000000000) truncated to 0xe8d60800 (-388626432); the generated code might be incorrect.
Warning: integer overflow: integer 0x430e23400 (18000000000) truncated to 0x30e23400 (820130816); the generated code might be incorrect.
ls -al _build/default/js/moc_js.bc.js
-r--r--r-- 1 crusso crusso 2456599 Aug  7 16:12 _build/default/js/moc_js.bc.js
crusso@crusso-Virtual-Machine:~/motoko/src$ 
```

* chore(deps): Bump actions/download-artifact from 4 to 5 (#5381)

Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/download-artifact/releases">actions/download-artifact's releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README.md by <a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a href="https://redirect.github.com/actions/download-artifact/pull/407">actions/download-artifact#407</a></li>
<li>BREAKING fix: inconsistent path behavior for single artifact downloads by ID by <a href="https://github.com/GrantBirki"><code>@​GrantBirki</code></a> in <a href="https://redirect.github.com/actions/download-artifact/pull/416">actions/download-artifact#416</a></li>
</ul>
<h2>v5.0.0</h2>
<h3>🚨 Breaking Change</h3>
<p>This release fixes an inconsistency in path behavior for single artifact downloads by ID. <strong>If you're downloading single artifacts by ID, the output path may change.</strong></p>
<h4>What Changed</h4>
<p>Previously, <strong>single artifact downloads</strong> behaved differently depending on how you specified the artifact:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted to <code>path/</code> (direct)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted to <code>path/my-artifact/</code> (nested)</li>
</ul>
<p>Now both methods are consistent:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted to <code>path/</code> (unchanged)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted to <code>path/</code> (fixed - now direct)</li>
</ul>
<h4>Migration Guide</h4>
<h5>✅ No Action Needed If:</h5>
<ul>
<li>You download artifacts by <strong>name</strong></li>
<li>You download <strong>multiple</strong> artifacts by ID</li>
<li>You already use <code>merge-multiple: true</code> as a workaround</li>
</ul>
<h5>⚠️ Action Required If:</h5>
<p>You download <strong>single artifacts by ID</strong> and your workflows expect the nested directory structure.</p>
<p><strong>Before v5 (nested structure):</strong></p>
<pre lang="yaml"><code>- uses: actions/download-artifact@v4
  with:
    artifact-ids: 12345
    path: dist
# Files were in: dist/my-artifact/
</code></pre>
<blockquote>
<p>Where <code>my-artifact</code> is the name of the artifact you previously uploaded</p>
</blockquote>
<p><strong>To maintain old behavior (if needed):</strong></p>
<pre lang="yaml"><code>&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/actions/download-artifact/commit/634f93cb2916e3fdff6788551b99b062d0335ce0"><code>634f93c</code></a> Merge pull request <a href="https://redirect.github.com/actions/download-artifact/issues/416">#416</a> from actions/single-artifact-id-download-path</li>
<li><a href="https://github.com/actions/download-artifact/commit/b19ff4302770b82aa4694b63703b547756dacce6"><code>b19ff43</code></a> refactor: resolve download path correctly in artifact download tests (mainly ...</li>
<li><a href="https://github.com/actions/download-artifact/commit/e262cbee4ab8c473c61c59a81ad8e9dc760e90db"><code>e262cbe</code></a> bundle dist</li>
<li><a href="https://github.com/actions/download-artifact/commit/bff23f9308ceb2f06d673043ea6311519be6a87b"><code>bff23f9</code></a> update docs</li>
<li><a href="https://github.com/actions/download-artifact/commit/fff8c148a8fdd56aa81fcb019f0b5f6c65700c4d"><code>fff8c14</code></a> fix download path logic when downloading a single artifact by id</li>
<li><a href="https://github.com/actions/download-artifact/commit/448e3f862ab3ef47aa50ff917776823c9946035b"><code>448e3f8</code></a> Merge pull request <a href="https://redirect.github.com/actions/download-artifact/issues/407">#407</a> from actions/nebuk89-patch-1</li>
<li><a href="https://github.com/actions/download-artifact/commit/47225c44b359a5155efdbbbc352041b3e249fb1b"><code>47225c4</code></a> Update README.md</li>
<li>See full diff in <a href="https://github.com/actions/download-artifact/compare/v4...v5">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=4&new-version=5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

* doc: update `core` migration guide (#5388)

* Update migration guide

* Update minimum versions

* Adjustments

* Mention 'latest dfx / Motoko version' instead of specific version numbers

* Briefly mention explicit minimum dfx/Motoko versions

* Update doc/md/12-base-core-migration.md

Co-authored-by: Claudio Russo <claudio@dfinity.org>

* Apply suggestions from code review

Co-authored-by: Claudio Russo <claudio@dfinity.org>

---------

Co-authored-by: Claudio Russo <claudio@dfinity.org>

* doc: reference `core` package (#5374)

* Replace usages of 'base' with 'core' in docs

* More

* Roll back unintentional change to 'Primitive types' table

* Update counter examples

* Update examples

* chore: update md/examples to use core (#5390)

* upgrade examples to use core

* add check for MOTOKO_BASE

* fix link to migration example

* Remove 14-language-manual.md

---------

Co-authored-by: Claudio Russo <claudio@dfinity.org>

* feat: Infer more call instantiations by partial argument inference (#5180)

* chore: add `motoko-core` artifacts to GitHub releases (#5398)

* Add 'motoko-core' artifacts to GitHub releases

* Simplify diff

* Fix

* doc: update migration guide (#5394)

Pending 1.0.0 release in case we make any other changes.

* Explanatory Upgrade Error Messages (#5391)

Trying to make upgrade compatibility messages (for DFX and Caffeine) more self-explanatory:
* Removing the unreadable hash suffixes from displayed type names
* Determining the actual inner-most type incompatibility cause
* Providing a path from stable variable down to the cause of mismatch
* Revised error messages, less verbose type displays, plus documentation link

* Fix Intra-Partition Allocator (#5396)

This fixes a scenario on memory pressure on very large heaps (6 GB currently), related to incremental partition allocation:
1. The allocator keeps a memory reserve for critical operations such as for the GC and upgrades.
2. A partition may be virtually allocated in such an exception moment.
3. The critical operation completes and the reserve is again put back in force.
4. Now, the incremental intra-partition allocator still remains in this partition (in reserve space) and must be able to complete the partition before a new partition in lower sub-reserve space can be used.

The fix can be applied through usual EOP upgrade to a Motoko canister that might be stuck by this issue.

* bugfix: add null <: opt t to IDL memory compatiblity check (#5404)

* chore(deps): Bump actions/checkout from 4 to 5 (#5392)

Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/checkout/releases">actions/checkout's releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update actions checkout to use node 24 by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
<li>Prepare v5.0.0 release by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2238">actions/checkout#2238</a></li>
</ul>
<h2>⚠️ Minimum Compatible Runner Version</h2>
<p><strong>v2.327.1</strong><br />
<a href="https://github.com/actions/runner/releases/tag/v2.327.1">Release Notes</a></p>
<p>Make sure your runner is updated to this version or newer to use this release.</p>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v4...v5.0.0">https://github.com/actions/checkout/compare/v4...v5.0.0</a></p>
<h2>v4.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>docs: update README.md by <a href="https://github.com/motss"><code>@​motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a href="https://github.com/benwells"><code>@​benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
<li>Prepare release v4.3.0 by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2237">actions/checkout#2237</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/motss"><code>@​motss</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li><a href="https://github.com/mouismail"><code>@​mouismail</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li><a href="https://github.com/benwells"><code>@​benwells</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li><a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v4...v4.3.0">https://github.com/actions/checkout/compare/v4...v4.3.0</a></p>
<h2>v4.2.2</h2>
<h2>What's Changed</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="https://github.com/jww3"><code>@​jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a href="https://github.com/jww3"><code>@​jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v4.2.1...v4.2.2">https://github.com/actions/checkout/compare/v4.2.1...v4.2.2</a></p>
<h2>v4.2.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Jcambass"><code>@​Jcambass</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/1919">actions/checkout#1919</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v4.2.0...v4.2.1">https://github.com/actions/checkout/compare/v4.2.0...v4.2.1</a></p>

</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>V5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>V4.3.0</h2>
<ul>
<li>docs: update README.md by <a href="https://github.com/motss"><code>@​motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a href="https://github.com/benwells"><code>@​benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="https://github.com/jww3"><code>@​jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a href="https://github.com/jww3"><code>@​jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>, <a href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4 updates by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable version. by <a href="https://github.com/jww3"><code>@​jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<h2>v4.1.5</h2>
<ul>
<li>Update NPM dependencies by <a href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li>
<li>Bump github/codeql-action from 2 to 3 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li>
<li>Bump actions/setup-node from 1 to 4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li>
<li>Bump actions/upload-artifact from 2 to 4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li>
<li>README: Suggest <code>user.email</code> to be <code>41898282+github-actions[bot]@users.noreply.github.com</code> by <a href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1707">actions/checkout#1707</a></li>
</ul>
<h2>v4.1.4</h2>
<ul>
<li>Disable <code>extensions.worktreeConfig</code> when disabling <code>sparse-checkout</code> by <a href="https://github.com/jww3"><code>@​jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1692">actions/checkout#1692</a></li>
<li>Add dependabot config by <a href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1688">actions/checkout#1688</a></li>
<li>Bump the minor-actions-dependencies group with 2 updates by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1693">actions/checkout#1693</a></li>
<li>Bump word-wrap from 1.2.3 to 1.2.5 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1643">actions/checkout#1643</a></li>
</ul>
<h2>v4.1.3</h2>

</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/actions/checkout/commit/08c6903cd8c0fde910a37f88322edcfb5dd907a8"><code>08c6903</code></a> Prepare v5.0.0 release (<a href="https://redirect.github.com/actions/checkout/issues/2238">#2238</a>)</li>
<li><a href="https://github.com/actions/checkout/commit/9f265659d3bb64ab1440b03b12f4d47a24320917"><code>9f26565</code></a> Update actions checkout to use node 24 (<a href="https://redirect.github.com/actions/checkout/issues/2226">#2226</a>)</li>
<li>See full diff in <a href="https://github.com/actions/checkout/compare/v4...v5">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4&new-version=5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

* chore: weekly `flake.lock` update (#5403)

Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action
as defined in [.github/workflows/update-flake-lock-trial.yml](https://github.com/dfinity/motoko/blob/master/.github/workflows/update-flake-lock-trial.yml)
and run in: https://github.com/dfinity/motoko/actions/runs/17014649021/attempts/1:

```
Flake lock file updates:

• Updated input 'ic-src':
    'github:dfinity/ic/d4379f3d1a3d69cad9e84c7dd734758e1098d29e?narHash=sha256-X2F16vUFL7e1tf5VWPKHWuLL%2B8/xF8ruLsDb91RQmPY%3D' (2025-06-06)
  → 'github:dfinity/ic/b6cf1a858dfa1634e763eff203a709afbd1d8bb0?narHash=sha256-i0QngtC8mVTzp5xNV3/GIbgfB8Vkd7gfg0L78AHf1oI%3D' (2025-08-16)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/8eb3b6a2366a7095939cd22f0dc0e9991313294b?narHash=sha256-bFufQGSAEYQgjtc4wMrobS5HWN0hDP%2BZX%2BzthYcml9U%3D' (2025-06-04)
  → 'github:NixOS/nixpkgs/50ab793786d9de88ee30ec4e4c24fb4236fc2674?narHash=sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT%2Bg%3D' (2025-06-30)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/d58933b88cef7a05e9677e94352fd6fedba402cd?narHash=sha256-9HNq3EHZIvvxXQyEn0sYOywcESF1Xqw2Q8J1ZewcXuk%3D' (2025-06-06)
  → 'github:oxalica/rust-overlay/07619500e5937cc4669f24fec355d18a8fec0165?narHash=sha256-NspGtm0ZpihxlFD628pvh5ZEhL/Q6/Z9XBpe3n6ZtEw%3D' (2025-08-16)
```

This PR is just to test if the above dependency bumps cause issues.
If checks fail this PR remains open so we can investigate.
If all checks succeed this PR is automatically closed.

* feat: Weak References in Motoko (#5363)

First implementation of Weak References in Motoko with GC and type system support. The main functionality so far is to dereference a weak reference and check if the object pointed at by it is still live (i.e., wasn't garbage collected).

So far, the API exposes the following:
1. Create a weak reference to an object, via `weakRef = Prim.allocWeakRef(object)`.
2. Dereference a weak reference, via `object = Prim.getWeak()`.
3. Check if a target of a weak reference is still alive, via `Prim.isLive(weakRef)`.

This all works by adding a new type in the compiler and a new tag type in the RTS for tracking everything. The most non-intrusive change that allowed for achieving the aforementioned functionality was to add: (1) a new data structure that collects all the Weak References during marking; and (2) a new GC step immediately after marking that goes through this Weak Reference data structure and checks whether objects they point to are still live. If not, the weak reference pointer is updated to be NULL.

The functionality of the PR covers the difficult case of upgrades that may fall within a GC cycle by ensuring that the metadata layout is compatible even with adding a new data structure.

* chore: Releasing 0.16.0 (#5405)

* feat: add program lifetime instruction counter (#5401)

This PR adds a new monotonic program/canister instruction counter; Will wrap around u64. Will be used by the CI pipeline for performance tests; Currently, drun reports instruction counters, but once we migrate to pocket-ic we don't have this feature. The counter introduced here can be used in a similar way.

* doc: add note for creating `motoko-core` tag during release process (#5410)

* bugfix: issue-5283 (repro and fix) (#5412)

Fix for issue #5283.

The await translation would crash in obscure cases. Turns out its due to a bug in ir/rename.ml that wasn't properly distinguishing labels from identifiers when renaming them.

The counter-example is this code from the repro

```
                       label satset for (satset in [1,2,4].vals()) {
                          if (4==5) {
                            
                            break satset;
                          }
                        };
```

This uses a label and identifier with the same name, and unless kept distinct, after broken renaming,  would result in the inner break referencing the new identifier for (inner) satset rather than the new label for (outer) satset.

The fix is for renaming to use a map with a domain that distinguishes identifers from labels. 
Even better would be if we didn't use the same type (string, yuck) for identifiers and labels, but that is a bigger refactoring for later.

* doc: migration guide tweaks (#5417)

Miscellaneous improvements to the `base` -> `core` migration guide.

* fix: warn (and ignore) parentheticals on `async*` calls and fix effect sequencing (#5415)

Fixes #5414.

Also make sure that the parenthetical is properly discarded on calls unless they result in `async` futures.

Also fixes an effect sequencing bug regarding parenthetical evaluation and register setting with subexpression evaluation.

* chore(license): removes modified boilerplate from license file (#5422)

This PR removes the modified appendix from the LICENSE file to ensure full compliance with the Apache 2.0 license, which should remain in its original, unmodified form. This change aligns our repositories with standard practices for license documentation.

* feat: Infer invariant when bound is isolated (no proper super/subtypes except Top/Bottom) (#5359)

* fix: Missing type note update (leaving `???` `Type.Pre`) in enhanced type inference path (#5423)

Fixes #5418

* feat: warn when `ignore`-ing an `async*` (#5419)

There are examples out there and this helps avoiding that mistake. Any `async*` value is inert until an `await*` forces it. `ignore`-ing it may drop the only reference to it, which means it has been built in vain. What people probably want is `ignore`-ing the `await*`-ed value.

* chore: Releasing 0.16.1 (#5424)

* `pocket-ic` integration first steps (#5161)

This PR aims to build a local `test-runner` that will completely replace our dependency on `drun`, which will be decommissioned soon. 

This PR does the following:
* Adds nix flake for checking out and building from source `pocket-ic` both in CI and local development. NB: the nix flake patches pocket-ic to not emit backtraces such that our string matching test framework doesn't complain about it.
* Small rust project (`test-runner`) that depends on `pocket-ic` and its rust library crate.
* CI pipeline is slightly optimized (some tests were running unnecessarily in multiple derivations).
* The instruction performance counter is now coming from the canisters reporting (through [#5401](#5401) instead of the Prometheus interface of drun); The `run.sh` script is modified accordingly.
* currently all tests run, with the exception of `upgrades.drun` (remains to be seen why).

NB: Developers need to be in a nix shell (`nix develop`) when running tests locally.

What needs to be done later is:
* figure out why `upgrades.drun` fails
* figure out a way to update pocket-ic related packages without too much manual intervention
* get rid of DRUN

* fix: Fix darwin x86 build (#5427)

see: #5425 

Nigthly Darwin x86_64 CI build failure due to rocks db compilation.

* fix: fix pocket-ic testing in the darwin x86 CI (#5434)

Fixes: #5433

* feat: parallel tests (#5431)

Running tests in parallel to speed up CI.

On my machine, running:
`EXTRA_MOC_ARGS="--sanity-checks --enhanced-orthogonal-persistence" time make -C run-drun/` (the debug mode tests)

took  33:34.10 (sequential) and now  8:27.29 (parallel).

The CI machines are different, but still should bring us a decent speedup.

* Update `core` migration guide (#5432)

Adds information for migrating from the `Heap`, `None`, `RBTree`, and `Trie` modules.

* feat: Remove drun from CI pipeline (#5436)

The `drun` tool has been replaced (successfully) with pocket-ic. This PR removes all traces of `drun` from the CI.

* chore: add test-runner tests (#5442)

This PR adds initial tests for the test-runner package and refines the nix setup to remove duplication and add a derivation for the test-runner tests.

* chore: add `List.at()` in the docs (#5445)

* Manual merge conflict resolution

* Merge branch 'master' into luc/stable-functions-softened

* Manual merge conflict resolution

* Manual merge conflict resolution

* Appease the formatter

* Manual merge conflict resolution

* Update test

* Update test_recovery.ml

* Update test_recovery.ml

* Fix merge

* Merge fix

* Fix tests

* Adjust test outputs

* Manual merge conflict resolution

* Update no-stable-functions-classical.tc.ok

* Stable Functions: Adjustments (#5475)

* Fix stable closure field acceses

* Fix name table

* Prototype: Persist by library path

* Redesign library qualified names

* Update documentation

* Adjust tests

* Adjust test case

---------

Co-authored-by: pr-automation-bot-public[bot] <189003650+pr-automation-bot-public[bot]@users.noreply.github.com>
Co-authored-by: Kamil Listopad <kamil.listopad@dfinity.org>
Co-authored-by: Gabor Greif <gabor@dfinity.org>
Co-authored-by: Christoph <christoph.hegemann@dfinity.org>
Co-authored-by: Claudio Russo <claudio@dfinity.org>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ryan Vandersmith <ryan.vandersmith@dfinity.org>
Co-authored-by: Alex Uta <alexandru.uta@gmail.com>
Co-authored-by: Jan Wendling <7381150+jwndlng@users.noreply.github.com>
@luc-blaeser luc-blaeser changed the base branch from master to luc/stable-functions September 12, 2025 13:03
@luc-blaeser luc-blaeser merged commit 84ed178 into luc/stable-functions Sep 12, 2025
7 checks passed
@luc-blaeser luc-blaeser deleted the luc/stable-functions-softened branch September 12, 2025 13:03
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.

3 participants