corrode
corrode copied to clipboard
Functions may be translated with wrong environment
Consider this program:
static int x;
static void f(void) {
x = 1;
}
void g(void) {
char *x;
f();
}
Because f
is static
, Corrode defers translating it until it encounters the call from g
. Because the translation was deferred, right now, it runs in the scope where the first call was encountered. That means that when it translates the assignment x = 1
, Corrode believes that the type of x
is char *
, not int
as it should be. The result is that f
translates this way:
unsafe extern fn f() {
x = 1i32 as (*mut u8);
}
Which is, of course, complete nonsense, and the Rust compiler sensibly reports "mismatched types" on the assignment. (This example also triggers issue #92 but this problem should be solved independently of that one.)
One way to solve this would be:
-
get
theEnvState
value at the beginning ofinterpretFunction
, so we have a reference to the right environment to use later. - Inside the block that begins with
mapExceptT (local setRetTy) $ scope $ do
, reset theEnvState
to the saved version. But this is a little tricky, because we must not reset theGlobalState
that's inside theEnvState
. So something like this should work:
lift (modify (\ current -> old { globalState = globalState current }))
Another way to solve this would do pretty much exactly the same thing, except you'd do it in runOnce
instead of in interpretFunction
, so that all deferred computations would be guaranteed to run in the environment as it stood at the time they were deferred. That's probably better.