Generally, the names of `case`-bound variables are allowed to shadow variables declared outside the enclosing `match`. However, in the case of nested patterns, Dafny generates an error if a bound variable shadows a variable outside the `match`.
```
datatype List = Nil | Cons(int, List)
method R(xs: List)
{
var a: int;
var b: int;
match xs
case Nil =>
case Cons(a, Nil()) => // this 'a' is allowed
case Cons(x, Cons(b, tail)) => // this 'b' (which is in a nested position) generates an error
}
function F(xs: List): int
{
var a := 4;
var b := 7;
match xs
case Nil => 0
case Cons(a, Nil()) => 1
case Cons(x, Cons(b, tail)) => 2
}
```
gives
```
test.dfy(28,20): Error: Duplicate parameter name: b
test.dfy(38,20): Error: Duplicate parameter name: b
```
Note in the example that the bound variable 'a', which occurs as a parameter to the top-level constructor, is allowed, even though it shadows the local variable `a`. That's good. However, Dafny produces an error for `b`. That's bad.
The bug arises for both `match` statements and `match` expressions, as the repro example above shows.
Rustan
```
datatype List = Nil | Cons(int, List)
method R(xs: List)
{
var a: int;
var b: int;
match xs
case Nil =>
case Cons(a, Nil()) => // this 'a' is allowed
case Cons(x, Cons(b, tail)) => // this 'b' (which is in a nested position) generates an error
}
function F(xs: List): int
{
var a := 4;
var b := 7;
match xs
case Nil => 0
case Cons(a, Nil()) => 1
case Cons(x, Cons(b, tail)) => 2
}
```
gives
```
test.dfy(28,20): Error: Duplicate parameter name: b
test.dfy(38,20): Error: Duplicate parameter name: b
```
Note in the example that the bound variable 'a', which occurs as a parameter to the top-level constructor, is allowed, even though it shadows the local variable `a`. That's good. However, Dafny produces an error for `b`. That's bad.
The bug arises for both `match` statements and `match` expressions, as the repro example above shows.
Rustan