consider this snippet
fn hello(branch: bool) -> int {
let y = if branch {
1
} else {
2
};
y
}
currently with the commit im working on, since branch is not known at compile time, both of the branches of the if get their result coerced to a runtime operand. for numeric literals, this means a result type is required, meaning let y needs to be let y: int for this code to compile.
to get us all on the same page, let's see the untyped IR for this block.
%26 = +0 func {
params: [
%bool_type
]
return_type: %int32_type
captures: []
body: %15 = -1 block [
%16 = -1 param(0)
%23 = -4 if(%16) {
yes: %18 = -7 block [
%17 = -8 number 1
%19 = -7 break(%18, %17)
]
no: %21 = -5 block [
%20 = -6 number 2
%22 = -5 break(%21, %20)
]
}
%24 = -1 coercion(%int32_type, %23)
%25 = -1 break(%15, %24)
]
}
is there a way we can resolve the coersion for %18 and %21 AFTER %23 already happens? it would mean that at %24, it would see %23 is unresolved, and propagate the type backwards. one of the problems is finding old, already committed blocks, and rebuilding them.
i'm not really sure how this will work in practice, as well as other situations where this behavior makes more sense to support. this is the same class of issue as something like
let arr = [];
arr.push("hello")
where the the ref arr is retroactively coerced to []string
Milestone: 0.3.0.