Unnecessary variables generated for record field values
In both ReScript 10.0.0-rc.1 and ReScript 9.1.4,
type options = {
a: int,
b: int,
}
@module("some-module")
external func: options => unit = "func"
let test = a => {
let options = {
a: a + 1,
b: 42,
}
func(options)
}
compiles to
import * as SomeModule from "some-module";
function test(a) {
var options_a = a + 1 | 0;
var options = {
a: options_a,
b: 42
};
SomeModule.func(options);
}
with an unnecessary variable options_a generated.
In ReScript 10, when making field b optional, an unnecessary variable options_b is generated in addition:
type options = {
a: int,
b?: int,
}
@module("some-module")
external func: options => unit = "func"
let test = a => {
let options = {
a: a + 1,
b: 42,
}
func(options)
}
compiles to
import * as SomeModule from "some-module";
function test(a) {
var options_a = a + 1 | 0;
var options_b = 42;
var options = {
a: options_a,
b: options_b
};
SomeModule.func(options);
}
Not sure what "unnecessary" refers to. Is this implied to be a regression? It seems not.
Not sure why this particular computation, out of all the possible computations, is expected to be inlined.
Is analogous code written directly and not generated through the use of options, inlined?
To clarify:
- I would have expected
options_ato be inlined. However, this is not a regression, as the behavior is the same in ReScript 9 and 10. - In ReScript 10, I would not have expected inlining behavior to be different depending on whether field
bis optional or not.
Is analogous code written directly and not generated through the use of options, inlined?
Not sure if that's what you mean, but
let test = a => {
func({
a: a + 1,
b: 42,
})
}
is indeed inlined:
function test(a) {
SomeModule.func({
a: a + 1 | 0,
b: 42
});
}
In this case, the output is the same irrespective of whether field b is optional or not.
How do you know that func does not have side effects?
Note that the second example is just sugar for using an option type in the record.
I don't know why it's relevant whether func has side effects.
As for
- In ReScript 10, I would not have expected inlining behavior to be different depending on whether field b is optional or not.
it seems that in general optimizations are not applied as soon as a record has at least one optional field, see also #5616.
You can't inline functions with side effects. And that might lead to generating different code.
It does not mean that the code cannot be simplified, it only suggests a possible reason for why it is how it is.