Goal
Add the inferred-return typed lambda form to ori_parse, with =-delimiter disambiguation via the shared try_parse_lambda_return_type() helper. Parser-only; reuses the existing ExprKind::Lambda lowering. The bare -> Type shape is parse-ambiguous with (x: int) -> x and resolves to E2005 at typeck (proposal Errata 2026-05-31), not a parse diagnostic.
Intelligence Reconnaissance
Queries (2026-05-31): scripts/intel-query.sh symbols "lambda" --repo ori; scripts/intel-query.sh similar parse_typed_lambda_body --repo rust,swift,go.
- [ori:compiler/ori_arc/src/lower/calls/lambda.rs]
lower_lambda— the new form reuses this lowering (sameExprKind::Lambdanode); no ARC change. - [ori:compiler/ori_eval/src/interpreter/can_eval/function_exp.rs]
eval_can_lambda— evaluator reuse confirmed; no eval change. - [ori] No symbol collision:
(x: T) -> bodyis a parser front-end change feeding the existing lambda pipeline. - Prior art (graph): typescript#40750, swift#11478, roc#9145 concern lambda-return-inference quality, not existence — Rust/Swift/Gleam/TS all infer it.
Implementation Sketch
ori_parse/src/grammar/expr/primary/collections.rs currently routes a parenthesized expression into parse_typed_lambda_body the moment a parameter is typed, then unconditionally requires -> type = body (E1005 when no return type, E1017 when no =). Replace that with the unified lambda_tail rule: after ->, speculatively parse a type; if = follows, it is the explicit-return form; otherwise restore the snapshot and parse the tail as a body expression, building ExprKind::Lambda { params, ret_ty: ParsedTypeId::INVALID, body }. The shared try_parse_lambda_return_type() helper already implements this; parse_typed_lambda_body reuses it (DRY). The bare -> Type case is parse-ambiguous with (x: int) -> x and resolves to a type-name-as-value E2005 at typeck (proposal Errata 2026-05-31), not a parse diagnostic.
Implementation Items
- Write the parser test matrix — positive pins (inferred, operator-body, multi-param) + negative pins (juxtaposition, mixed-param E1018) added in
tests/parser.rs; the conformance corpus is the integration gate. - In
collections.rs, routeparse_typed_lambda_bodythrough the SSOTtry_parse_lambda_return_type()helper (snapshot →parse_type()→=-delimiter), the same disambiguation the()-lambda path uses. DRY — no parallel logic. - Explicit-return branch:
type =consumed,ret_ty= the annotated type (via the shared helper). - Inferred-return branch: no
=→ret_ty: ParsedTypeId::INVALID, body parsed as an expression. - Bare-
-> Typeedge case — REFINED (per proposal Errata 2026-05-31): parse-ambiguous with the valid(x: int) -> xform, so no parse diagnostic;(x: int) -> intparses as bodyintand the type-name-as-value fails type inference (E2005). Clause 14 updated to match. - Clear the
ori_parseclippy regression (task #5 — landed5bdb49e19). - Verify debug + dual-execution parity;
cargo test -p ori_parse --lib(470 pass), interpreter + LLVM both green onlambdas.ori(30 each).
Spec References
- Proposal:
compiler_repo/docs/ori_lang/proposals/approved/typed-lambda-inferred-return-proposal.md§Design / §Disambiguation. - Grammar:
grammar.ebnf:550-553(lambda/simple_lambda/typed_lambda). - Spec clause:
14-expressions.md:149. - Parser rules:
parse.md §SN-3(speculative parse / snapshot), §PR-6 (lambda layering).
Tests
Matrix dimensions (rows = lambda shape; columns = expected parse outcome):
| Shape | Expected |
|---|---|
(x: int) -> x * 2 | Lambda{ret_ty: INVALID}, body x * 2 |
(x: int) -> int = x | Lambda{ret_ty: int}, body x |
(x: int) -> Foo == y | Lambda{ret_ty: INVALID}, body Foo == y |
(a: int, b: int) -> a - b | Lambda{ret_ty: INVALID}, two typed params |
(x: int) -> int (no body) | parses as body int; type-name-as-value → E2005 at typeck |
(x) -> x | untyped simple_lambda (unchanged) |
(x: int, y) -> ... | E1018 (mixed typed/untyped, unchanged) |
- Positive pins: typed-param inferred-return parses to
ret_ty: INVALID; explicit-return parses to the annotated type. - Negative pins: juxtaposed
(x: int) -> int xis still rejected (trailing token, no longerE1017); mixed params still emitE1018. - Rust unit tests in
ori_parse(token-stream / AST-shape assertions); the.oriconformance corpus is the section-11 gate.