c218d875 · core f63c1e69 · built 2026-10-26 22:39 UTCIntegration testing — v0.14.1
Session run: 2026-10-26 · against develop at 9ce74e03 (all 53 milestone issues closed;
the two process gates — rfc.py check and the pending-marker release gate — pass).
Result: PASS — clear to release. The language owner recorded the language-visible changes as
exceptions to the patch rule on 2026-10-26 (see Release type below).
Features exercised
Twenty language-visible capabilities, from the ## v0.14.1 changelog section (diagnostics block
and fixes block). No RFC reached 4-implemented this milestone; RFC-0181 reached 3-integrated
(#1480, its slice issues #1483 and #1484 are closed and listed below). They are grouped into seven
for the matrix. The grouping is a deliberate departure from a 20×20 grid: several members of a
group share one code path, and a per-feature grid would invite cells claimed without a fixture.
| Group | Capabilities |
|---|---|
| A diagnostics | method call on a function value is T0003 (#1242); whole value where a narrowed type is required, wording (#1458); record diff in unification errors (#1483); T0032 advice for an anonymous open record in a return type (#1484) |
| B block-local type identity | same-named block-local records with equal field names (#1553); zero-field local types (#1555); outer type restored after an inner block (#1561); identity kept on annotations and enum values (#1568) |
| C block-local type usability | generic local struct/record/enum (#1556); local enums constructed and matched (#1557); struct patterns on local structs (#1565) |
| D namespaces and duplicates | T0037 duplicate top-level name (#1560); separate type and value namespaces, imports bring both (#1571); T0034 duplicate method in an aspect impl or aspect (#1229) |
| E value shadowing and visibility | a local shadows a same-named module function used as a value (#1578); private function beside a public imported type is T0009 (#1575) |
| F reserved and core names | intrinsic type names reserved, T0038 (#1582); shadowing Perhaps/Result keeps core behaviour on values from std (#1585) |
| G core paths and aliases | std::core::T in a type position (#1587); variants of an aliased core enum (#1588) |
Interaction matrix
Upper triangle; the diagonal is covered per PR. Each cell is a fixture (path under
metel-interpreter/tests/integration/sources/), n/a: <reason>, or BUG→#N (documented by a
skip-tagged fixture). Fixtures added by this session are marked new.
| B | C | D | E | F | G | |
|---|---|---|---|---|---|---|
| A | BUG→#1618 (diff not applied to a named local record) typechecking/records/neg_a_record_missing_a_field_for_a_named_record_reports_a_record_diff | BUG→#1618 (same cause) | n/a: wording of expression diagnostics against declaration-level errors; no program reaches both messages | typechecking/structs/neg_method_on_a_function_value_held_in_a_local_is_t0003 new | n/a: no shared path | n/a: no shared path |
| B | — | evaluator/enums/local_generic_enum_holding_a_local_struct new; evaluator/move_check/two_local_generic_records_of_one_name_keep_distinct_identity new; evaluator/move_check/zero_field_generic_local_record_is_copied new; evaluator/records/projection_on_same_named_local_records_in_two_functions new | BUG→#1615 (a local type does not shadow a module-level one) evaluator/structs/a_local_struct_shadows_a_module_level_struct new | evaluator/structs/an_inner_block_type_and_a_local_let_shadow_independently new | BUG→#1615 for a core name evaluator/enums/a_local_enum_shadows_a_std_core_type new; typechecking/types/neg_a_local_type_named_like_an_intrinsic_type_is_t0038 | BUG→#1615 (a local Perhaps beside a qualified std::core::Perhaps) |
| C | — | n/a: T0037 and the namespace rules apply to top-level declarations only; local types live in a block scope | evaluator/functions/every_binding_kind_shadows_a_module_function new (pattern binding against a local struct) | typechecking/types/neg_a_local_type_named_like_an_intrinsic_type_is_t0038 | n/a: no shared path | |
| D | — | evaluator/structs/a_private_function_does_not_hide_a_public_type_of_its_name; typechecking/types/neg_private_function_beside_an_imported_public_type_is_t0009 | evaluator/functions/intrinsic_type_names_stay_usable_as_function_and_let_names new; module_semantics/an_imported_perhaps_of_the_users_own_sits_beside_the_core_one new | module_semantics/an_aliased_import_brings_a_type_and_a_function_of_one_name new | ||
| E | — | n/a: value shadowing and type-name reservation are different namespaces | n/a: value shadowing does not touch type-path resolution | |||
| F | — | module_semantics/an_imported_perhaps_of_the_users_own_sits_beside_the_core_one new; BUG→#1616 for the expression form evaluator/perhaps_result/a_qualified_core_variant_builds_the_core_value_when_the_module_shadows_it new |
Within-group pairs that carry their own coverage: C×C evaluator/enums/local_enum_variant_holding_a_local_record_is_matched_by_pattern
new and evaluator/generics/local_generic_struct_record_and_enum; D×D
typechecking/types/neg_struct_and_enum_of_one_name_is_t0037,
typechecking/structs/duplicate_method_in_one_aspect_declaration_is_t0034; G×G
module_semantics/aliased_core_enum_constructs_variants_under_its_annotation,
module_semantics/std_core_qualified_path_names_a_core_type.
Against the subsystem table in /milestone-integration-test: the milestone adds a subsystem the
table does not list — name resolution and declaration identity (groups B to G). Treated as
high-risk for this session, and every high-risk pair above is either a fixture or a documented bug.
The older high-risk subsystems were crossed with the new features rather than skipped:
closures × block-local types (evaluator/closures/local_types_cross_closure_boundaries new, under
--move-check), move/ownership × block-local identity (the three move_check/ fixtures),
pattern matching × shadowing (every_binding_kind_shadows_a_module_function), and record
narrowing × same-named local records (records/projection_on_same_named_local_records_in_two_functions).
Fixtures added
Metel-core#1619 (tracking issue #1617). Passing: 10 single-file evaluator fixtures, 2 module
fixtures and 1 negative fixture. Documenting a finding (skip-tagged, each fails if unskipped):
4 fixtures for #1615, #1616 and #1618.
Findings
None is a regression: each reproduces identically on the released v0.14.0 binary. None is soundness. Under the bug policy they are filed to Backlog and do not block the release.
- #1615 — a block-local
struct/record/enumdoes not shadow a same-named module-level, imported orstd::coretype, contrary tospec.declarations.variables.scoping-and-shadowing.legality-1andmodules.md.severity:incorrect. Deferred to Backlog. - #1616 —
std::core::Result::Ok { .. }in an expression resolves to the module's ownResultwhen it declares one. The #1587 changelog entry says the expression form "already worked"; that holds only when nothing shadows the name.severity:incorrect. Deferred to Backlog. - #1618 — the #1483 record diff covers a structural record type but not a named
record, which still printscannot unify { x: ?1 } with P. The changelog entry for #1483 overstates the fix.severity:diagnostic. Deferred to Backlog.
Release type
The milestone and ROADMAP.md type v0.14.1 as a patch: "no accepted programs change". The
## v0.14.1 changelog section also contains changes to which programs are accepted:
- previously accepted, now rejected:
T0037duplicate top-level names (#1560),T0038reserved intrinsic type names (#1582),T0034extended to aspect impls and aspects (#1229); - previously rejected, now accepted: block-local enums (#1557), generic block-local types
(#1556), struct patterns on block-local structs (#1565), types named after an inner block ends
(#1561), imports bringing a name in every namespace (#1571), a local
letshadowing a module function (#1578), shadowedPerhaps/Resultkeeping core behaviour (#1585), and the qualified and aliased core types (#1587, #1588); - under
--move-checkonly: block-local type identity (#1553, #1555, #1568).
Decision (language owner, 2026-10-26): these are recorded as exceptions on the v0.14.1 milestone, next to the earlier #1587/#1588 exception, and the release ships as v0.14.1. The milestone description lists each. This is not a test result; it is the answer to the release-type question this session raised, and it does not change the verdict.
Full-tree verification
On develop at 9ce74e03:
cargo test --release --workspace: all suites pass (1514 integration, 427, 97, 26, 4, 3 and the doc-test targets; 0 failures). With the session fixtures (#1619): 1530 integration, 0 failures.cargo clippy --release --workspace --lib -- -W clippy::pedantic: no warnings.move-check-count:skipped_generic_bodies_user_total=0(baseline 18).user_move_violations=100, inside the 84 to 108 range the v0.14.0 sessions recorded; this session did not re-triage each one.check_doc_examples.pyoverREADME.md, the tutorials and the spec: 196 passed, 0 failed, 89 skipped.
Freeze reconciliation (2026-10-26)
Commits landed on develop after 9ce74e03 and before the tag. None changes language-visible
behaviour, so the PASS above stands against the frozen tip: the session's own fixtures
(metel-core#1619, tests only, and the docs gitlink bumps #1620 and the release commit); and the
release commit itself (crate version bump, typechecker.md notes, docs gitlink). The tip the tag
points at is named in the release report, not here.
Sign-off
All high-risk pairs have a fixture or a filed finding. The full release suite is green on 9ce74e03.
The three findings are deferred to Backlog, none a regression or a soundness bug. Clear for
/cut-release v0.14.1.