Types(TY7): match exhaustiveness, unreachable arms, per-arm narrowing #32
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/032-types-ty7-match-exhaustiveness-unreachable-arm"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Types(TY7): match exhaustiveness, unreachable arms, per-arm narrowing
Along the way:
Touches 46 files:
docs/impl/03-parser.md,docs/impl/08-diagnostics.md,docs/impl/resolution/N6-hir-lowering.md,docs/impl/slices.md,docs/impl/type-system/TY7-exhaustive-match-and-narrowing.md,docs/syntax.mdand 40 more.A clear improvement. The change in
src/rust/crates/ck_types/src/check_block.rsis the part I would have argued for.@ -76,0 +129,4 @@ExprKind::List { elements } if elements.is_empty());let value_ty = if is_empty_list {self.record_type(value, ann.clone());record_typeis cloned on what looks like a hot path. Is the ownership forced here, or can this borrow?@ -482,0 +550,4 @@/// statement / tail. Shares the code with the [TY5](../../../../docs/impl/type-system/TY5-method-call-sugar.md)/// method-on-`Nothing` form (both are dead-code-after-`Nothing`).#[must_use]pub fn e0720_dead_stmt(primary: Span) -> Diagnostic {e0720_dead_stmtis public. Does anything outside the crate call it, or is it pub because that was easier? Every public item is a promise.It can borrow. The clone of
record_typewas left over from before the lifetime was threaded throughsrc/rust/crates/ck_types/src/check_block.rs, and it is gone.Nothing outside calls
e0720_dead_stmt. It is pub(crate) insrc/rust/crates/ck_types/src/diag.rsnow.Read it too. No objection to
src/rust/crates/ck_types/src/check_block.rs.Lock and implement the value-position precedence of the type-algebra operators `is` / `is not` / `and` / `or` / `not` (syntax.md + 03-parser.md), retiring the E0047 "precedence undecided" bail. This is the front-end prerequisite for TY7 flow narrowing, which needs `Assert::guard(x is T)` to actually parse. - Precedence (loosest tier, below `with`): `is`/`is not` (left = 8, RHS a single type via parse_type_expr_single — no or-union fold), `not` (prefix, right = 7), `and` (6,7), `or` (4,5). So `x is Cat or x is Dog` is two tests joined by `or`, and `not x is Int` is `not (x is Int)`. - New CST node `TypeTestExpr`; `and`/`or` reuse `BinaryExpr`, `not` reuses `UnaryExpr`. AST accessor `TypeTestExpr { value, ty, is_negated }`. - HIR: `ExprKind::TypeTest { value, negated }`, `BinOp::And`/`Or`, `UnOp::Not`. The asserted type is read off the CST at synth time (the manifest-read discipline), not carried in the node. - Resolver lowering split into `lower/operators.rs` (binary/unary/type-test) to stay under the R3 cap; only the unavoidable `syntax_kind.rs` enum growth touches the ratchet (798 -> 802, justified). - TypeTest synthesizes `Bool` in the checker (narrowing recognizer is the next sliver); ck_eval defers it to Unit like `match`. All four gates green: build, test, clippy -D warnings, link checker.