Description
The semantics of Expr(:new)
with missing parameters for immutables are underspecified.
In particular, we need to decide whether the value is undefined or merely possibly uninitialized.
The primary difference between the two is how we represent this to LLVM. In particular undefined values may change on every access. As an illustrative example, consider:
struct Foo
x::UInt8
Foo() = new()
Foo(x::UInt8) = new(x)
end
function bar(i...)
f = Foo(i...)
y = (f.x + UInt8(128))
if f.x >= UInt8(128)
println("World")
end
if y >= UInt8(128)
println("Hello")
end
return nothing
end
What happens when you call bar()
depends on LLVM versions and other considerations, but on my local copy, it prints nothing. However, any actual UInt8
value would print either "Hello" or "World". Unfortunately, there isn't really a way to say to llvm "I don't care what this value is, but it always has to be the same". If we decide we do not like the above behavior, we'll have to initialize all (stack? - will have to check what assumptions LLVM makes) allocations visible to LLVM.