This is really just a natural consequence of understanding what data constructors are in a compiler.
Imagine you had the following code:
fn f(x: f32) -> f32 { x*x }
fn main() {
let f(x) = 9.0;
println!("{}", x);
}
This program will fail to compile:
error[E0532]: expected tuple struct or tuple variant, found function `f`
--> src/main.rs:5:9
|
5 | let f(x) = 9.0;
| ^ not a tuple struct or tuple variant
Interestingly, it doesn't fail to compile because it doesn't make sense. It does make sense, and the solution is x = 3.0
. The problem is that the compiler cannot automatically compute the inverse of a function. (I believe it still an open question of whether there exist functions that have no inverses, but regardless, it is not computationally feasible to do this.) But if we could magically compute function inverses, there'd be no reason to not allow this kind of code.
In the meantime, the compiler has special builtin functions that it does understand how to invert: struct and tuple constructors. Because they are builtins with fixed, trivial semantics, they are allowed in patterns like this. (And because struct constructors have special syntax, you don't use function call syntax in patterns either, but this Fblah { x }
syntax instead. Though there's no fundamental reason structs can't use function call syntax, as they already do for user-defined constructors.)
In other words, pattern matching is just algebra, and data constructors are just functions whose inverses are known to the compiler.