Any reason not to allow it? Not at the language level. There's a design question as to how it's represented in `IOperation`, but that's not a language question.
However, there are also difficult questions with 4: can it be used before it is declared? Is it visible across partial classes? These are all questions that could be answered, but we are also a little uneasy making it so easy to "accidentally" declare an extra private field, in case some function members close over it.
That latter concern could be alleviated by reducing to option 3, but now the scope is weird, and most of the usefulness is gone. May as well reduce to 2 or 1 then.
We'll go with option 1. If you want to use expression variables to carry information between initializers, you'll instead have to do do your initialization in the constructor body.
However, to do this we would need to perform much more semantic analysis of the query than we do today, before we lower. It feels out of touch with the syntactic flavor of queries today.
Instead, a more reasonable approach may be to make it easier to carry multiple range variables forward from a `let` (and maybe `from`) clause, using deconstruction syntax:
We should allow expression variables in queries, but keep them scoped to the individual query clauses. In other words, they aren't range variables. They are normal variables scoped by the lambdas that we translate into.
The [proposal](https://github.com/dotnet/csharplang/blob/master/proposals/caller-argument-expression.md) calls for an extra parameter with a default value (which is then replaced by the expression passed as an argument for the parameter designated in the attribute). This means that in a tie breaker situation, existing methods would match better than new ones that differ only by having this extra argument.
We are not comfortable with those just yet. We'd need to work on the details. For now we are suspicious of having a record of a lot of different information, and of the number of proposed ones in [csharplang/issues/87](https://github.com/dotnet/csharplang/issues/87).
[csharplang/issues/103](https://github.com/dotnet/csharplang/issues/103) and [csharplang/issues/104](https://github.com/dotnet/csharplang/issues/104) propose to allow the `Enum` and `Delegate` types as constraints. No special meaning, just stop disallowing them. That's a starting point. Adding keywords `enum` and `delegate` could be discussed later.
[csharplang/issues/187](https://github.com/dotnet/csharplang/issues/187) proposes a contextual keyword `unmanaged`; we would represent it by putting a `ModReq` in the constraint of the parameter. It implies the `struct` constraint.
Reference assemblies are a problem: some tools produce reference assemblies that remove private fields from structs, which already leads to semantic problems in the compiler (definite assignment, allowing pointers to them), and now would lead to more. That's fundamentally not a language problem though.