Details about $expr is $pat (or let $pat = $expr as a boolean expression) can be found in discussions of RFC #2260. One big problem of is is how bindings are made. Without name bindings it is not sufficient to replace let … else. 2260 compare is with several other languages (C#, Kotlin, TypeScript), but:
-
Swift’s
$pat ~= $exprdoes not support name binding -
In C# 7’s
$expr is $pat, a declaration statement will be inserted before the current statement, i.e. the following two statements are equivalent:return f(c is float d); // <=> // declaration inserted float d; // when we evaluate `c is float d`, it will be expanded to bool _result = c is float; if (_result) { d = (float)c; } return f(_result);This is possible only because every type has a default value in C#. The variable
dwill be “leaked” after callingf, and has a value of 0 ifcis not a float. This treatment is not possible in Rust. -
Kotlin’s smart cast (
$expr is $ty) and TypeScript’s type guards (e.g.$expr instanceof $ty) is not used for pattern matching (destructuring). They alter the type of$exprso that type-specific fields will become available.
There is an attempt to create a precise scoping rule in https://github.com/rust-lang/rfcs/pull/2260#issuecomment-354525996.