Skip to main content
Next (unreleased) · docs c218d875 · core f63c1e69 · built 2026-10-26 22:39 UTC

Move-check skips generic bodies whose placeholder lacks a row bound or bound methods

Limitation​

Move-check analyses a generic body by constructing it against symbolic arguments, one __metel_move_check_generic_N placeholder per generic parameter. The placeholder carries no row bound, and some bound-provided methods are not registered on it, so a body that reads a row-bound field (value.y with T: { y: i64, .. }) or calls a method supplied by a match/extend bound cannot be constructed. Move-check then records the body as skipped (record_skipped_generic_body) and prints a warning instead of analysing it. Reproduced against current develop:

fun f<record T: { y: i64, .. }>(value: T) -> (T, T, i64) {
let n := value.y;
let a := value;
let b := value;
(a, b, n)
}
warning: move checking could not analyze generic body …: [I0001] internal error: no field `y` on `__metel_move_check_generic_17`

exit status 0. Without the value.y line the same body is analysed and the second let is rejected (T0019).

Impact​

Under --move-check, a use-after-move inside a skipped generic body is not reported; only the warning is printed and the run succeeds. Move-check is opt-in (LIMIT-MOVE-CHECK-001), so the exposure is limited to programs that use it. The symptom is tracked as metel-core#1226.

Affects​

Resolution​

Resolved under metel-core#273. Generic free functions and impl methods are analysed from the abstract bodies retained by definition-time checking (ADR-0063), so a body that reads a row-bound field or uses a bound-provided method no longer depends on a placeholder that lacks them. The integration corpus has no unchecked generic body and no abstract-body fallback, and a regression test asserts it.

A body that still cannot be analysed is no longer skipped with a warning. --move-check fails with I0011 (a distinct analysis error, not T0019), so an incomplete analysis cannot authorize execution.

The example above now reports T0019 on the second let.