Transformation for parameter dependent contexts
Summary:
This diff adds rewriting for $x::C contexts.
```
function f(A $x)[$x::Co]: void {}
==>
function f<
T$x as A,
T$x@Co,
>(
T$x $x
)[$x::Co]: void where
T$x@Co = T$x::Co
{}
```
The transformation also handles the case of ?A, and when $x's type is already a type parameter. The latter is useful because the runtime will enforce $x as an A (upper bound enforcement) in this function
```
function f<T as A>(T $x): void {}
```
but it will not do so in the following case
```
function f<T as A, T$x as T>(T$x $x): void {}
```
The use of Rust here is a tradeoff. Pattern matching is very poor which makes this less readable than if the rewrite happened in Naming, but mutating the data structures in place as opposed to rebuilding them in a functional world ends up being less cumbersome overall.
Reviewed By: losvald
Differential Revision:
D25608862
fbshipit-source-id:
3e14bf3825f8a1cd6f83d0511b7f641c0de89eb9